aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kernel/Makefile3
-rw-r--r--arch/powerpc/kernel/dma_64.c240
-rw-r--r--arch/powerpc/kernel/ibmebus.c6
-rw-r--r--arch/powerpc/kernel/iommu.c6
-rw-r--r--arch/powerpc/kernel/of_platform.c9
-rw-r--r--arch/powerpc/kernel/pci_64.c26
-rw-r--r--arch/powerpc/kernel/pci_direct_iommu.c98
-rw-r--r--arch/powerpc/kernel/pci_iommu.c164
-rw-r--r--arch/powerpc/kernel/setup_64.c1
-rw-r--r--arch/powerpc/kernel/vio.c94
-rw-r--r--arch/powerpc/platforms/cell/iommu.c21
-rw-r--r--arch/powerpc/platforms/iseries/iommu.c12
-rw-r--r--arch/powerpc/platforms/iseries/pci.c2
-rw-r--r--arch/powerpc/platforms/pasemi/setup.c16
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c90
-rw-r--r--arch/powerpc/platforms/pseries/pci_dlpar.c4
-rw-r--r--arch/powerpc/sysdev/dart_iommu.c31
-rw-r--r--include/asm-powerpc/device.h19
-rw-r--r--include/asm-powerpc/dma-mapping.h180
-rw-r--r--include/asm-powerpc/ibmebus.h1
-rw-r--r--include/asm-powerpc/iommu.h20
-rw-r--r--include/asm-powerpc/iseries/iommu.h4
-rw-r--r--include/asm-powerpc/machdep.h4
-rw-r--r--include/asm-powerpc/of_device.h2
-rw-r--r--include/asm-powerpc/pci.h8
-rw-r--r--include/asm-powerpc/vio.h1
26 files changed, 451 insertions, 611 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 04fdbe568d7b..eba8d118e214 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -62,8 +62,7 @@ obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o
62module-$(CONFIG_PPC64) += module_64.o 62module-$(CONFIG_PPC64) += module_64.o
63obj-$(CONFIG_MODULES) += $(module-y) 63obj-$(CONFIG_MODULES) += $(module-y)
64 64
65pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o pci_iommu.o \ 65pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o iomap.o
66 pci_direct_iommu.o iomap.o
67pci32-$(CONFIG_PPC32) := pci_32.o 66pci32-$(CONFIG_PPC32) := pci_32.o
68obj-$(CONFIG_PCI) += $(pci64-y) $(pci32-y) 67obj-$(CONFIG_PCI) += $(pci64-y) $(pci32-y)
69kexec-$(CONFIG_PPC64) := machine_kexec_64.o 68kexec-$(CONFIG_PPC64) := machine_kexec_64.o
diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
index 6c168f6ea142..4e6551199782 100644
--- a/arch/powerpc/kernel/dma_64.c
+++ b/arch/powerpc/kernel/dma_64.c
@@ -1,151 +1,185 @@
1/* 1/*
2 * Copyright (C) 2004 IBM Corporation 2 * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corporation
3 * 3 *
4 * Implements the generic device dma API for ppc64. Handles 4 * Provide default implementations of the DMA mapping callbacks for
5 * the pci and vio busses 5 * directly mapped busses and busses using the iommu infrastructure
6 */ 6 */
7 7
8#include <linux/device.h> 8#include <linux/device.h>
9#include <linux/dma-mapping.h> 9#include <linux/dma-mapping.h>
10/* Include the busses we support */
11#include <linux/pci.h>
12#include <asm/vio.h>
13#include <asm/ibmebus.h>
14#include <asm/scatterlist.h>
15#include <asm/bug.h> 10#include <asm/bug.h>
11#include <asm/iommu.h>
12#include <asm/abs_addr.h>
16 13
17static struct dma_mapping_ops *get_dma_ops(struct device *dev) 14/*
18{ 15 * Generic iommu implementation
19#ifdef CONFIG_PCI 16 */
20 if (dev->bus == &pci_bus_type)
21 return &pci_dma_ops;
22#endif
23#ifdef CONFIG_IBMVIO
24 if (dev->bus == &vio_bus_type)
25 return &vio_dma_ops;
26#endif
27#ifdef CONFIG_IBMEBUS
28 if (dev->bus == &ibmebus_bus_type)
29 return &ibmebus_dma_ops;
30#endif
31 return NULL;
32}
33 17
34int dma_supported(struct device *dev, u64 mask) 18static inline unsigned long device_to_mask(struct device *dev)
35{ 19{
36 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 20 if (dev->dma_mask && *dev->dma_mask)
21 return *dev->dma_mask;
22 /* Assume devices without mask can take 32 bit addresses */
23 return 0xfffffffful;
24}
37 25
38 BUG_ON(!dma_ops);
39 26
40 return dma_ops->dma_supported(dev, mask); 27/* Allocates a contiguous real buffer and creates mappings over it.
28 * Returns the virtual address of the buffer and sets dma_handle
29 * to the dma address (mapping) of the first page.
30 */
31static void *dma_iommu_alloc_coherent(struct device *dev, size_t size,
32 dma_addr_t *dma_handle, gfp_t flag)
33{
34 return iommu_alloc_coherent(dev->archdata.dma_data, size, dma_handle,
35 device_to_mask(dev), flag,
36 dev->archdata.numa_node);
41} 37}
42EXPORT_SYMBOL(dma_supported);
43 38
44int dma_set_mask(struct device *dev, u64 dma_mask) 39static void dma_iommu_free_coherent(struct device *dev, size_t size,
40 void *vaddr, dma_addr_t dma_handle)
45{ 41{
46#ifdef CONFIG_PCI 42 iommu_free_coherent(dev->archdata.dma_data, size, vaddr, dma_handle);
47 if (dev->bus == &pci_bus_type)
48 return pci_set_dma_mask(to_pci_dev(dev), dma_mask);
49#endif
50#ifdef CONFIG_IBMVIO
51 if (dev->bus == &vio_bus_type)
52 return -EIO;
53#endif /* CONFIG_IBMVIO */
54#ifdef CONFIG_IBMEBUS
55 if (dev->bus == &ibmebus_bus_type)
56 return -EIO;
57#endif
58 BUG();
59 return 0;
60} 43}
61EXPORT_SYMBOL(dma_set_mask);
62 44
63void *dma_alloc_coherent(struct device *dev, size_t size, 45/* Creates TCEs for a user provided buffer. The user buffer must be
64 dma_addr_t *dma_handle, gfp_t flag) 46 * contiguous real kernel storage (not vmalloc). The address of the buffer
47 * passed here is the kernel (virtual) address of the buffer. The buffer
48 * need not be page aligned, the dma_addr_t returned will point to the same
49 * byte within the page as vaddr.
50 */
51static dma_addr_t dma_iommu_map_single(struct device *dev, void *vaddr,
52 size_t size,
53 enum dma_data_direction direction)
65{ 54{
66 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 55 return iommu_map_single(dev->archdata.dma_data, vaddr, size,
67 56 device_to_mask(dev), direction);
68 BUG_ON(!dma_ops);
69
70 return dma_ops->alloc_coherent(dev, size, dma_handle, flag);
71} 57}
72EXPORT_SYMBOL(dma_alloc_coherent);
73 58
74void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, 59
75 dma_addr_t dma_handle) 60static void dma_iommu_unmap_single(struct device *dev, dma_addr_t dma_handle,
61 size_t size,
62 enum dma_data_direction direction)
76{ 63{
77 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 64 iommu_unmap_single(dev->archdata.dma_data, dma_handle, size, direction);
65}
78 66
79 BUG_ON(!dma_ops);
80 67
81 dma_ops->free_coherent(dev, size, cpu_addr, dma_handle); 68static int dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist,
69 int nelems, enum dma_data_direction direction)
70{
71 return iommu_map_sg(dev->archdata.dma_data, sglist, nelems,
72 device_to_mask(dev), direction);
82} 73}
83EXPORT_SYMBOL(dma_free_coherent);
84 74
85dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, size_t size, 75static void dma_iommu_unmap_sg(struct device *dev, struct scatterlist *sglist,
86 enum dma_data_direction direction) 76 int nelems, enum dma_data_direction direction)
87{ 77{
88 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 78 iommu_unmap_sg(dev->archdata.dma_data, sglist, nelems, direction);
89
90 BUG_ON(!dma_ops);
91
92 return dma_ops->map_single(dev, cpu_addr, size, direction);
93} 79}
94EXPORT_SYMBOL(dma_map_single);
95 80
96void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, 81/* We support DMA to/from any memory page via the iommu */
97 enum dma_data_direction direction) 82static int dma_iommu_dma_supported(struct device *dev, u64 mask)
98{ 83{
99 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 84 struct iommu_table *tbl = dev->archdata.dma_data;
100 85
101 BUG_ON(!dma_ops); 86 if (!tbl || tbl->it_offset > mask) {
102 87 printk(KERN_INFO
103 dma_ops->unmap_single(dev, dma_addr, size, direction); 88 "Warning: IOMMU offset too big for device mask\n");
89 if (tbl)
90 printk(KERN_INFO
91 "mask: 0x%08lx, table offset: 0x%08lx\n",
92 mask, tbl->it_offset);
93 else
94 printk(KERN_INFO "mask: 0x%08lx, table unavailable\n",
95 mask);
96 return 0;
97 } else
98 return 1;
104} 99}
105EXPORT_SYMBOL(dma_unmap_single);
106 100
107dma_addr_t dma_map_page(struct device *dev, struct page *page, 101struct dma_mapping_ops dma_iommu_ops = {
108 unsigned long offset, size_t size, 102 .alloc_coherent = dma_iommu_alloc_coherent,
109 enum dma_data_direction direction) 103 .free_coherent = dma_iommu_free_coherent,
110{ 104 .map_single = dma_iommu_map_single,
111 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 105 .unmap_single = dma_iommu_unmap_single,
106 .map_sg = dma_iommu_map_sg,
107 .unmap_sg = dma_iommu_unmap_sg,
108 .dma_supported = dma_iommu_dma_supported,
109};
110EXPORT_SYMBOL(dma_iommu_ops);
112 111
113 BUG_ON(!dma_ops); 112/*
113 * Generic direct DMA implementation
114 */
114 115
115 return dma_ops->map_single(dev, page_address(page) + offset, size, 116static void *dma_direct_alloc_coherent(struct device *dev, size_t size,
116 direction); 117 dma_addr_t *dma_handle, gfp_t flag)
118{
119 void *ret;
120
121 /* TODO: Maybe use the numa node here too ? */
122 ret = (void *)__get_free_pages(flag, get_order(size));
123 if (ret != NULL) {
124 memset(ret, 0, size);
125 *dma_handle = virt_to_abs(ret);
126 }
127 return ret;
117} 128}
118EXPORT_SYMBOL(dma_map_page);
119 129
120void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, 130static void dma_direct_free_coherent(struct device *dev, size_t size,
121 enum dma_data_direction direction) 131 void *vaddr, dma_addr_t dma_handle)
122{ 132{
123 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 133 free_pages((unsigned long)vaddr, get_order(size));
134}
124 135
125 BUG_ON(!dma_ops); 136static dma_addr_t dma_direct_map_single(struct device *dev, void *ptr,
137 size_t size,
138 enum dma_data_direction direction)
139{
140 return virt_to_abs(ptr);
141}
126 142
127 dma_ops->unmap_single(dev, dma_address, size, direction); 143static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr,
144 size_t size,
145 enum dma_data_direction direction)
146{
128} 147}
129EXPORT_SYMBOL(dma_unmap_page);
130 148
131int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, 149static int dma_direct_map_sg(struct device *dev, struct scatterlist *sg,
132 enum dma_data_direction direction) 150 int nents, enum dma_data_direction direction)
133{ 151{
134 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 152 int i;
135 153
136 BUG_ON(!dma_ops); 154 for (i = 0; i < nents; i++, sg++) {
155 sg->dma_address = page_to_phys(sg->page) + sg->offset;
156 sg->dma_length = sg->length;
157 }
137 158
138 return dma_ops->map_sg(dev, sg, nents, direction); 159 return nents;
139} 160}
140EXPORT_SYMBOL(dma_map_sg);
141 161
142void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, 162static void dma_direct_unmap_sg(struct device *dev, struct scatterlist *sg,
143 enum dma_data_direction direction) 163 int nents, enum dma_data_direction direction)
144{ 164{
145 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 165}
146
147 BUG_ON(!dma_ops);
148 166
149 dma_ops->unmap_sg(dev, sg, nhwentries, direction); 167static int dma_direct_dma_supported(struct device *dev, u64 mask)
168{
169 /* Could be improved to check for memory though it better be
170 * done via some global so platforms can set the limit in case
171 * they have limited DMA windows
172 */
173 return mask >= DMA_32BIT_MASK;
150} 174}
151EXPORT_SYMBOL(dma_unmap_sg); 175
176struct dma_mapping_ops dma_direct_ops = {
177 .alloc_coherent = dma_direct_alloc_coherent,
178 .free_coherent = dma_direct_free_coherent,
179 .map_single = dma_direct_map_single,
180 .unmap_single = dma_direct_unmap_single,
181 .map_sg = dma_direct_map_sg,
182 .unmap_sg = dma_direct_unmap_sg,
183 .dma_supported = dma_direct_dma_supported,
184};
185EXPORT_SYMBOL(dma_direct_ops);
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index 39db7a3affe1..8e515797de6a 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -112,7 +112,7 @@ static int ibmebus_dma_supported(struct device *dev, u64 mask)
112 return 1; 112 return 1;
113} 113}
114 114
115struct dma_mapping_ops ibmebus_dma_ops = { 115static struct dma_mapping_ops ibmebus_dma_ops = {
116 .alloc_coherent = ibmebus_alloc_coherent, 116 .alloc_coherent = ibmebus_alloc_coherent,
117 .free_coherent = ibmebus_free_coherent, 117 .free_coherent = ibmebus_free_coherent,
118 .map_single = ibmebus_map_single, 118 .map_single = ibmebus_map_single,
@@ -176,6 +176,10 @@ static struct ibmebus_dev* __devinit ibmebus_register_device_common(
176 dev->ofdev.dev.bus = &ibmebus_bus_type; 176 dev->ofdev.dev.bus = &ibmebus_bus_type;
177 dev->ofdev.dev.release = ibmebus_dev_release; 177 dev->ofdev.dev.release = ibmebus_dev_release;
178 178
179 dev->ofdev.dev.archdata.of_node = dev->ofdev.node;
180 dev->ofdev.dev.archdata.dma_ops = &ibmebus_dma_ops;
181 dev->ofdev.dev.archdata.numa_node = of_node_to_nid(dev->ofdev.node);
182
179 /* An ibmebusdev is based on a of_device. We have to change the 183 /* An ibmebusdev is based on a of_device. We have to change the
180 * bus type to use our own DMA mapping operations. 184 * bus type to use our own DMA mapping operations.
181 */ 185 */
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index ba6b7256084b..95edad4faf26 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -258,9 +258,9 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
258 spin_unlock_irqrestore(&(tbl->it_lock), flags); 258 spin_unlock_irqrestore(&(tbl->it_lock), flags);
259} 259}
260 260
261int iommu_map_sg(struct device *dev, struct iommu_table *tbl, 261int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
262 struct scatterlist *sglist, int nelems, 262 int nelems, unsigned long mask,
263 unsigned long mask, enum dma_data_direction direction) 263 enum dma_data_direction direction)
264{ 264{
265 dma_addr_t dma_next = 0, dma_addr; 265 dma_addr_t dma_next = 0, dma_addr;
266 unsigned long flags; 266 unsigned long flags;
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c
index 25850ade8e68..7a0e77af7c9f 100644
--- a/arch/powerpc/kernel/of_platform.c
+++ b/arch/powerpc/kernel/of_platform.c
@@ -22,7 +22,7 @@
22#include <asm/dcr.h> 22#include <asm/dcr.h>
23#include <asm/of_device.h> 23#include <asm/of_device.h>
24#include <asm/of_platform.h> 24#include <asm/of_platform.h>
25 25#include <asm/topology.h>
26 26
27/* 27/*
28 * The list of OF IDs below is used for matching bus types in the 28 * The list of OF IDs below is used for matching bus types in the
@@ -221,6 +221,13 @@ struct of_device* of_platform_device_create(struct device_node *np,
221 dev->dev.parent = parent; 221 dev->dev.parent = parent;
222 dev->dev.bus = &of_platform_bus_type; 222 dev->dev.bus = &of_platform_bus_type;
223 dev->dev.release = of_release_dev; 223 dev->dev.release = of_release_dev;
224 dev->dev.archdata.of_node = np;
225 dev->dev.archdata.numa_node = of_node_to_nid(np);
226
227 /* We do not fill the DMA ops for platform devices by default.
228 * This is currently the responsibility of the platform code
229 * to do such, possibly using a device notifier
230 */
224 231
225 if (bus_id) 232 if (bus_id)
226 strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE); 233 strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE);
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 9a6bb80a8cd4..88b78484b944 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -61,7 +61,7 @@ void iSeries_pcibios_init(void);
61 61
62LIST_HEAD(hose_list); 62LIST_HEAD(hose_list);
63 63
64struct dma_mapping_ops pci_dma_ops; 64struct dma_mapping_ops *pci_dma_ops;
65EXPORT_SYMBOL(pci_dma_ops); 65EXPORT_SYMBOL(pci_dma_ops);
66 66
67int global_phb_number; /* Global phb counter */ 67int global_phb_number; /* Global phb counter */
@@ -1205,15 +1205,35 @@ void __devinit pcibios_fixup_device_resources(struct pci_dev *dev,
1205} 1205}
1206EXPORT_SYMBOL(pcibios_fixup_device_resources); 1206EXPORT_SYMBOL(pcibios_fixup_device_resources);
1207 1207
1208void __devinit pcibios_setup_new_device(struct pci_dev *dev)
1209{
1210 struct dev_archdata *sd = &dev->dev.archdata;
1211
1212 sd->of_node = pci_device_to_OF_node(dev);
1213
1214 DBG("PCI device %s OF node: %s\n", pci_name(dev),
1215 sd->of_node ? sd->of_node->full_name : "<none>");
1216
1217 sd->dma_ops = pci_dma_ops;
1218#ifdef CONFIG_NUMA
1219 sd->numa_node = pcibus_to_node(dev->bus);
1220#else
1221 sd->numa_node = -1;
1222#endif
1223 if (ppc_md.pci_dma_dev_setup)
1224 ppc_md.pci_dma_dev_setup(dev);
1225}
1226EXPORT_SYMBOL(pcibios_setup_new_device);
1208 1227
1209static void __devinit do_bus_setup(struct pci_bus *bus) 1228static void __devinit do_bus_setup(struct pci_bus *bus)
1210{ 1229{
1211 struct pci_dev *dev; 1230 struct pci_dev *dev;
1212 1231
1213 ppc_md.iommu_bus_setup(bus); 1232 if (ppc_md.pci_dma_bus_setup)
1233 ppc_md.pci_dma_bus_setup(bus);
1214 1234
1215 list_for_each_entry(dev, &bus->devices, bus_list) 1235 list_for_each_entry(dev, &bus->devices, bus_list)
1216 ppc_md.iommu_dev_setup(dev); 1236 pcibios_setup_new_device(dev);
1217 1237
1218 /* Read default IRQs and fixup if necessary */ 1238 /* Read default IRQs and fixup if necessary */
1219 list_for_each_entry(dev, &bus->devices, bus_list) { 1239 list_for_each_entry(dev, &bus->devices, bus_list) {
diff --git a/arch/powerpc/kernel/pci_direct_iommu.c b/arch/powerpc/kernel/pci_direct_iommu.c
deleted file mode 100644
index 72ce082ce738..000000000000
--- a/arch/powerpc/kernel/pci_direct_iommu.c
+++ /dev/null
@@ -1,98 +0,0 @@
1/*
2 * Support for DMA from PCI devices to main memory on
3 * machines without an iommu or with directly addressable
4 * RAM (typically a pmac with 2Gb of RAM or less)
5 *
6 * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel.crashing.org)
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 */
13
14#include <linux/kernel.h>
15#include <linux/pci.h>
16#include <linux/delay.h>
17#include <linux/string.h>
18#include <linux/init.h>
19#include <linux/bootmem.h>
20#include <linux/mm.h>
21#include <linux/dma-mapping.h>
22
23#include <asm/sections.h>
24#include <asm/io.h>
25#include <asm/prom.h>
26#include <asm/pci-bridge.h>
27#include <asm/machdep.h>
28#include <asm/pmac_feature.h>
29#include <asm/abs_addr.h>
30#include <asm/ppc-pci.h>
31
32static void *pci_direct_alloc_coherent(struct device *hwdev, size_t size,
33 dma_addr_t *dma_handle, gfp_t flag)
34{
35 void *ret;
36
37 ret = (void *)__get_free_pages(flag, get_order(size));
38 if (ret != NULL) {
39 memset(ret, 0, size);
40 *dma_handle = virt_to_abs(ret);
41 }
42 return ret;
43}
44
45static void pci_direct_free_coherent(struct device *hwdev, size_t size,
46 void *vaddr, dma_addr_t dma_handle)
47{
48 free_pages((unsigned long)vaddr, get_order(size));
49}
50
51static dma_addr_t pci_direct_map_single(struct device *hwdev, void *ptr,
52 size_t size, enum dma_data_direction direction)
53{
54 return virt_to_abs(ptr);
55}
56
57static void pci_direct_unmap_single(struct device *hwdev, dma_addr_t dma_addr,
58 size_t size, enum dma_data_direction direction)
59{
60}
61
62static int pci_direct_map_sg(struct device *hwdev, struct scatterlist *sg,
63 int nents, enum dma_data_direction direction)
64{
65 int i;
66
67 for (i = 0; i < nents; i++, sg++) {
68 sg->dma_address = page_to_phys(sg->page) + sg->offset;
69 sg->dma_length = sg->length;
70 }
71
72 return nents;
73}
74
75static void pci_direct_unmap_sg(struct device *hwdev, struct scatterlist *sg,
76 int nents, enum dma_data_direction direction)
77{
78}
79
80static int pci_direct_dma_supported(struct device *dev, u64 mask)
81{
82 return mask < 0x100000000ull;
83}
84
85static struct dma_mapping_ops pci_direct_ops = {
86 .alloc_coherent = pci_direct_alloc_coherent,
87 .free_coherent = pci_direct_free_coherent,
88 .map_single = pci_direct_map_single,
89 .unmap_single = pci_direct_unmap_single,
90 .map_sg = pci_direct_map_sg,
91 .unmap_sg = pci_direct_unmap_sg,
92 .dma_supported = pci_direct_dma_supported,
93};
94
95void __init pci_direct_iommu_init(void)
96{
97 pci_dma_ops = pci_direct_ops;
98}
diff --git a/arch/powerpc/kernel/pci_iommu.c b/arch/powerpc/kernel/pci_iommu.c
deleted file mode 100644
index 0688b2534acb..000000000000
--- a/arch/powerpc/kernel/pci_iommu.c
+++ /dev/null
@@ -1,164 +0,0 @@
1/*
2 * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
3 *
4 * Rewrite, cleanup, new allocation schemes:
5 * Copyright (C) 2004 Olof Johansson, IBM Corporation
6 *
7 * Dynamic DMA mapping support, platform-independent parts.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24
25#include <linux/init.h>
26#include <linux/types.h>
27#include <linux/slab.h>
28#include <linux/mm.h>
29#include <linux/spinlock.h>
30#include <linux/string.h>
31#include <linux/pci.h>
32#include <linux/dma-mapping.h>
33#include <asm/io.h>
34#include <asm/prom.h>
35#include <asm/iommu.h>
36#include <asm/pci-bridge.h>
37#include <asm/machdep.h>
38#include <asm/ppc-pci.h>
39
40/*
41 * We can use ->sysdata directly and avoid the extra work in
42 * pci_device_to_OF_node since ->sysdata will have been initialised
43 * in the iommu init code for all devices.
44 */
45#define PCI_GET_DN(dev) ((struct device_node *)((dev)->sysdata))
46
47static inline struct iommu_table *device_to_table(struct device *hwdev)
48{
49 struct pci_dev *pdev;
50
51 if (!hwdev) {
52 pdev = ppc64_isabridge_dev;
53 if (!pdev)
54 return NULL;
55 } else
56 pdev = to_pci_dev(hwdev);
57
58 return PCI_DN(PCI_GET_DN(pdev))->iommu_table;
59}
60
61
62static inline unsigned long device_to_mask(struct device *hwdev)
63{
64 struct pci_dev *pdev;
65
66 if (!hwdev) {
67 pdev = ppc64_isabridge_dev;
68 if (!pdev) /* This is the best guess we can do */
69 return 0xfffffffful;
70 } else
71 pdev = to_pci_dev(hwdev);
72
73 if (pdev->dma_mask)
74 return pdev->dma_mask;
75
76 /* Assume devices without mask can take 32 bit addresses */
77 return 0xfffffffful;
78}
79
80
81/* Allocates a contiguous real buffer and creates mappings over it.
82 * Returns the virtual address of the buffer and sets dma_handle
83 * to the dma address (mapping) of the first page.
84 */
85static void *pci_iommu_alloc_coherent(struct device *hwdev, size_t size,
86 dma_addr_t *dma_handle, gfp_t flag)
87{
88 return iommu_alloc_coherent(device_to_table(hwdev), size, dma_handle,
89 device_to_mask(hwdev), flag,
90 pcibus_to_node(to_pci_dev(hwdev)->bus));
91}
92
93static void pci_iommu_free_coherent(struct device *hwdev, size_t size,
94 void *vaddr, dma_addr_t dma_handle)
95{
96 iommu_free_coherent(device_to_table(hwdev), size, vaddr, dma_handle);
97}
98
99/* Creates TCEs for a user provided buffer. The user buffer must be
100 * contiguous real kernel storage (not vmalloc). The address of the buffer
101 * passed here is the kernel (virtual) address of the buffer. The buffer
102 * need not be page aligned, the dma_addr_t returned will point to the same
103 * byte within the page as vaddr.
104 */
105static dma_addr_t pci_iommu_map_single(struct device *hwdev, void *vaddr,
106 size_t size, enum dma_data_direction direction)
107{
108 return iommu_map_single(device_to_table(hwdev), vaddr, size,
109 device_to_mask(hwdev), direction);
110}
111
112
113static void pci_iommu_unmap_single(struct device *hwdev, dma_addr_t dma_handle,
114 size_t size, enum dma_data_direction direction)
115{
116 iommu_unmap_single(device_to_table(hwdev), dma_handle, size, direction);
117}
118
119
120static int pci_iommu_map_sg(struct device *pdev, struct scatterlist *sglist,
121 int nelems, enum dma_data_direction direction)
122{
123 return iommu_map_sg(pdev, device_to_table(pdev), sglist,
124 nelems, device_to_mask(pdev), direction);
125}
126
127static void pci_iommu_unmap_sg(struct device *pdev, struct scatterlist *sglist,
128 int nelems, enum dma_data_direction direction)
129{
130 iommu_unmap_sg(device_to_table(pdev), sglist, nelems, direction);
131}
132
133/* We support DMA to/from any memory page via the iommu */
134static int pci_iommu_dma_supported(struct device *dev, u64 mask)
135{
136 struct iommu_table *tbl = device_to_table(dev);
137
138 if (!tbl || tbl->it_offset > mask) {
139 printk(KERN_INFO "Warning: IOMMU table offset too big for device mask\n");
140 if (tbl)
141 printk(KERN_INFO "mask: 0x%08lx, table offset: 0x%08lx\n",
142 mask, tbl->it_offset);
143 else
144 printk(KERN_INFO "mask: 0x%08lx, table unavailable\n",
145 mask);
146 return 0;
147 } else
148 return 1;
149}
150
151struct dma_mapping_ops pci_iommu_ops = {
152 .alloc_coherent = pci_iommu_alloc_coherent,
153 .free_coherent = pci_iommu_free_coherent,
154 .map_single = pci_iommu_map_single,
155 .unmap_single = pci_iommu_unmap_single,
156 .map_sg = pci_iommu_map_sg,
157 .unmap_sg = pci_iommu_unmap_sg,
158 .dma_supported = pci_iommu_dma_supported,
159};
160
161void pci_iommu_init(void)
162{
163 pci_dma_ops = pci_iommu_ops;
164}
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index b0f1c82df994..f7ad64acf47e 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -33,6 +33,7 @@
33#include <linux/serial.h> 33#include <linux/serial.h>
34#include <linux/serial_8250.h> 34#include <linux/serial_8250.h>
35#include <linux/bootmem.h> 35#include <linux/bootmem.h>
36#include <linux/pci.h>
36#include <asm/io.h> 37#include <asm/io.h>
37#include <asm/kdump.h> 38#include <asm/kdump.h>
38#include <asm/prom.h> 39#include <asm/prom.h>
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index ed007878d1bf..a80f8f1d2e5d 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -81,15 +81,15 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
81 struct iommu_table *tbl; 81 struct iommu_table *tbl;
82 unsigned long offset, size; 82 unsigned long offset, size;
83 83
84 dma_window = get_property(dev->dev.platform_data, 84 dma_window = get_property(dev->dev.archdata.of_node,
85 "ibm,my-dma-window", NULL); 85 "ibm,my-dma-window", NULL);
86 if (!dma_window) 86 if (!dma_window)
87 return NULL; 87 return NULL;
88 88
89 tbl = kmalloc(sizeof(*tbl), GFP_KERNEL); 89 tbl = kmalloc(sizeof(*tbl), GFP_KERNEL);
90 90
91 of_parse_dma_window(dev->dev.platform_data, dma_window, 91 of_parse_dma_window(dev->dev.archdata.of_node, dma_window,
92 &tbl->it_index, &offset, &size); 92 &tbl->it_index, &offset, &size);
93 93
94 /* TCE table size - measured in tce entries */ 94 /* TCE table size - measured in tce entries */
95 tbl->it_size = size >> IOMMU_PAGE_SHIFT; 95 tbl->it_size = size >> IOMMU_PAGE_SHIFT;
@@ -117,7 +117,8 @@ static const struct vio_device_id *vio_match_device(
117{ 117{
118 while (ids->type[0] != '\0') { 118 while (ids->type[0] != '\0') {
119 if ((strncmp(dev->type, ids->type, strlen(ids->type)) == 0) && 119 if ((strncmp(dev->type, ids->type, strlen(ids->type)) == 0) &&
120 device_is_compatible(dev->dev.platform_data, ids->compat)) 120 device_is_compatible(dev->dev.archdata.of_node,
121 ids->compat))
121 return ids; 122 return ids;
122 ids++; 123 ids++;
123 } 124 }
@@ -198,9 +199,9 @@ EXPORT_SYMBOL(vio_unregister_driver);
198/* vio_dev refcount hit 0 */ 199/* vio_dev refcount hit 0 */
199static void __devinit vio_dev_release(struct device *dev) 200static void __devinit vio_dev_release(struct device *dev)
200{ 201{
201 if (dev->platform_data) { 202 if (dev->archdata.of_node) {
202 /* XXX free TCE table */ 203 /* XXX should free TCE table */
203 of_node_put(dev->platform_data); 204 of_node_put(dev->archdata.of_node);
204 } 205 }
205 kfree(to_vio_dev(dev)); 206 kfree(to_vio_dev(dev));
206} 207}
@@ -210,7 +211,7 @@ static void __devinit vio_dev_release(struct device *dev)
210 * @of_node: The OF node for this device. 211 * @of_node: The OF node for this device.
211 * 212 *
212 * Creates and initializes a vio_dev structure from the data in 213 * Creates and initializes a vio_dev structure from the data in
213 * of_node (dev.platform_data) and adds it to the list of virtual devices. 214 * of_node and adds it to the list of virtual devices.
214 * Returns a pointer to the created vio_dev or NULL if node has 215 * Returns a pointer to the created vio_dev or NULL if node has
215 * NULL device_type or compatible fields. 216 * NULL device_type or compatible fields.
216 */ 217 */
@@ -240,8 +241,6 @@ struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
240 if (viodev == NULL) 241 if (viodev == NULL)
241 return NULL; 242 return NULL;
242 243
243 viodev->dev.platform_data = of_node_get(of_node);
244
245 viodev->irq = irq_of_parse_and_map(of_node, 0); 244 viodev->irq = irq_of_parse_and_map(of_node, 0);
246 245
247 snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address); 246 snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address);
@@ -254,7 +253,10 @@ struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
254 if (unit_address != NULL) 253 if (unit_address != NULL)
255 viodev->unit_address = *unit_address; 254 viodev->unit_address = *unit_address;
256 } 255 }
257 viodev->iommu_table = vio_build_iommu_table(viodev); 256 viodev->dev.archdata.of_node = of_node_get(of_node);
257 viodev->dev.archdata.dma_ops = &dma_iommu_ops;
258 viodev->dev.archdata.dma_data = vio_build_iommu_table(viodev);
259 viodev->dev.archdata.numa_node = of_node_to_nid(of_node);
258 260
259 /* init generic 'struct device' fields: */ 261 /* init generic 'struct device' fields: */
260 viodev->dev.parent = &vio_bus_device.dev; 262 viodev->dev.parent = &vio_bus_device.dev;
@@ -285,10 +287,11 @@ static int __init vio_bus_init(void)
285#ifdef CONFIG_PPC_ISERIES 287#ifdef CONFIG_PPC_ISERIES
286 if (firmware_has_feature(FW_FEATURE_ISERIES)) { 288 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
287 iommu_vio_init(); 289 iommu_vio_init();
288 vio_bus_device.iommu_table = &vio_iommu_table; 290 vio_bus_device.dev.archdata.dma_ops = &dma_iommu_ops;
291 vio_bus_device.dev.archdata.dma_data = &vio_iommu_table;
289 iSeries_vio_dev = &vio_bus_device.dev; 292 iSeries_vio_dev = &vio_bus_device.dev;
290 } 293 }
291#endif 294#endif /* CONFIG_PPC_ISERIES */
292 295
293 err = bus_register(&vio_bus_type); 296 err = bus_register(&vio_bus_type);
294 if (err) { 297 if (err) {
@@ -336,7 +339,7 @@ static ssize_t name_show(struct device *dev,
336static ssize_t devspec_show(struct device *dev, 339static ssize_t devspec_show(struct device *dev,
337 struct device_attribute *attr, char *buf) 340 struct device_attribute *attr, char *buf)
338{ 341{
339 struct device_node *of_node = dev->platform_data; 342 struct device_node *of_node = dev->archdata.of_node;
340 343
341 return sprintf(buf, "%s\n", of_node ? of_node->full_name : "none"); 344 return sprintf(buf, "%s\n", of_node ? of_node->full_name : "none");
342} 345}
@@ -353,62 +356,6 @@ void __devinit vio_unregister_device(struct vio_dev *viodev)
353} 356}
354EXPORT_SYMBOL(vio_unregister_device); 357EXPORT_SYMBOL(vio_unregister_device);
355 358
356static dma_addr_t vio_map_single(struct device *dev, void *vaddr,
357 size_t size, enum dma_data_direction direction)
358{
359 return iommu_map_single(to_vio_dev(dev)->iommu_table, vaddr, size,
360 ~0ul, direction);
361}
362
363static void vio_unmap_single(struct device *dev, dma_addr_t dma_handle,
364 size_t size, enum dma_data_direction direction)
365{
366 iommu_unmap_single(to_vio_dev(dev)->iommu_table, dma_handle, size,
367 direction);
368}
369
370static int vio_map_sg(struct device *dev, struct scatterlist *sglist,
371 int nelems, enum dma_data_direction direction)
372{
373 return iommu_map_sg(dev, to_vio_dev(dev)->iommu_table, sglist,
374 nelems, ~0ul, direction);
375}
376
377static void vio_unmap_sg(struct device *dev, struct scatterlist *sglist,
378 int nelems, enum dma_data_direction direction)
379{
380 iommu_unmap_sg(to_vio_dev(dev)->iommu_table, sglist, nelems, direction);
381}
382
383static void *vio_alloc_coherent(struct device *dev, size_t size,
384 dma_addr_t *dma_handle, gfp_t flag)
385{
386 return iommu_alloc_coherent(to_vio_dev(dev)->iommu_table, size,
387 dma_handle, ~0ul, flag, -1);
388}
389
390static void vio_free_coherent(struct device *dev, size_t size,
391 void *vaddr, dma_addr_t dma_handle)
392{
393 iommu_free_coherent(to_vio_dev(dev)->iommu_table, size, vaddr,
394 dma_handle);
395}
396
397static int vio_dma_supported(struct device *dev, u64 mask)
398{
399 return 1;
400}
401
402struct dma_mapping_ops vio_dma_ops = {
403 .alloc_coherent = vio_alloc_coherent,
404 .free_coherent = vio_free_coherent,
405 .map_single = vio_map_single,
406 .unmap_single = vio_unmap_single,
407 .map_sg = vio_map_sg,
408 .unmap_sg = vio_unmap_sg,
409 .dma_supported = vio_dma_supported,
410};
411
412static int vio_bus_match(struct device *dev, struct device_driver *drv) 359static int vio_bus_match(struct device *dev, struct device_driver *drv)
413{ 360{
414 const struct vio_dev *vio_dev = to_vio_dev(dev); 361 const struct vio_dev *vio_dev = to_vio_dev(dev);
@@ -422,13 +369,14 @@ static int vio_hotplug(struct device *dev, char **envp, int num_envp,
422 char *buffer, int buffer_size) 369 char *buffer, int buffer_size)
423{ 370{
424 const struct vio_dev *vio_dev = to_vio_dev(dev); 371 const struct vio_dev *vio_dev = to_vio_dev(dev);
425 struct device_node *dn = dev->platform_data; 372 struct device_node *dn;
426 const char *cp; 373 const char *cp;
427 int length; 374 int length;
428 375
429 if (!num_envp) 376 if (!num_envp)
430 return -ENOMEM; 377 return -ENOMEM;
431 378
379 dn = dev->archdata.of_node;
432 if (!dn) 380 if (!dn)
433 return -ENODEV; 381 return -ENODEV;
434 cp = get_property(dn, "compatible", &length); 382 cp = get_property(dn, "compatible", &length);
@@ -465,7 +413,7 @@ struct bus_type vio_bus_type = {
465*/ 413*/
466const void *vio_get_attribute(struct vio_dev *vdev, char *which, int *length) 414const void *vio_get_attribute(struct vio_dev *vdev, char *which, int *length)
467{ 415{
468 return get_property(vdev->dev.platform_data, which, length); 416 return get_property(vdev->dev.archdata.of_node, which, length);
469} 417}
470EXPORT_SYMBOL(vio_get_attribute); 418EXPORT_SYMBOL(vio_get_attribute);
471 419
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index aca4c3db0dde..0e6ab8a55ef7 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -255,9 +255,6 @@ static void enable_mapping(void __iomem *base, void __iomem *mmio_base)
255 set_iost_origin(mmio_base); 255 set_iost_origin(mmio_base);
256} 256}
257 257
258static void iommu_dev_setup_null(struct pci_dev *d) { }
259static void iommu_bus_setup_null(struct pci_bus *b) { }
260
261struct cell_iommu { 258struct cell_iommu {
262 unsigned long base; 259 unsigned long base;
263 unsigned long mmio_base; 260 unsigned long mmio_base;
@@ -306,12 +303,15 @@ static void cell_do_map_iommu(struct cell_iommu *iommu,
306 } 303 }
307} 304}
308 305
309static void iommu_devnode_setup(struct device_node *d) 306static void pci_dma_cell_bus_setup(struct pci_bus *b)
310{ 307{
311 const unsigned int *ioid; 308 const unsigned int *ioid;
312 unsigned long map_start, map_size, token; 309 unsigned long map_start, map_size, token;
313 const unsigned long *dma_window; 310 const unsigned long *dma_window;
314 struct cell_iommu *iommu; 311 struct cell_iommu *iommu;
312 struct device_node *d;
313
314 d = pci_bus_to_OF_node(b);
315 315
316 ioid = get_property(d, "ioid", NULL); 316 ioid = get_property(d, "ioid", NULL);
317 if (!ioid) 317 if (!ioid)
@@ -330,12 +330,6 @@ static void iommu_devnode_setup(struct device_node *d)
330 cell_do_map_iommu(iommu, *ioid, map_start, map_size); 330 cell_do_map_iommu(iommu, *ioid, map_start, map_size);
331} 331}
332 332
333static void iommu_bus_setup(struct pci_bus *b)
334{
335 struct device_node *d = (struct device_node *)b->sysdata;
336 iommu_devnode_setup(d);
337}
338
339 333
340static int cell_map_iommu_hardcoded(int num_nodes) 334static int cell_map_iommu_hardcoded(int num_nodes)
341{ 335{
@@ -499,16 +493,13 @@ void cell_init_iommu(void)
499 493
500 if (setup_bus) { 494 if (setup_bus) {
501 pr_debug("%s: IOMMU mapping activated\n", __FUNCTION__); 495 pr_debug("%s: IOMMU mapping activated\n", __FUNCTION__);
502 ppc_md.iommu_dev_setup = iommu_dev_setup_null; 496 ppc_md.pci_dma_bus_setup = pci_dma_cell_bus_setup;
503 ppc_md.iommu_bus_setup = iommu_bus_setup;
504 } else { 497 } else {
505 pr_debug("%s: IOMMU mapping activated, " 498 pr_debug("%s: IOMMU mapping activated, "
506 "no device action necessary\n", __FUNCTION__); 499 "no device action necessary\n", __FUNCTION__);
507 /* Direct I/O, IOMMU off */ 500 /* Direct I/O, IOMMU off */
508 ppc_md.iommu_dev_setup = iommu_dev_setup_null;
509 ppc_md.iommu_bus_setup = iommu_bus_setup_null;
510 } 501 }
511 } 502 }
512 503
513 pci_dma_ops = cell_iommu_ops; 504 pci_dma_ops = &cell_iommu_ops;
514} 505}
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index 218817d13c5c..ee0a4e42e4f0 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>
@@ -168,7 +169,7 @@ static struct iommu_table *iommu_table_find(struct iommu_table * tbl)
168} 169}
169 170
170 171
171void iommu_devnode_init_iSeries(struct device_node *dn) 172void iommu_devnode_init_iSeries(struct pci_dev *pdev, struct device_node *dn)
172{ 173{
173 struct iommu_table *tbl; 174 struct iommu_table *tbl;
174 struct pci_dn *pdn = PCI_DN(dn); 175 struct pci_dn *pdn = PCI_DN(dn);
@@ -186,19 +187,14 @@ void iommu_devnode_init_iSeries(struct device_node *dn)
186 pdn->iommu_table = iommu_init_table(tbl, -1); 187 pdn->iommu_table = iommu_init_table(tbl, -1);
187 else 188 else
188 kfree(tbl); 189 kfree(tbl);
190 pdev->dev.archdata.dma_data = pdn->iommu_table;
189} 191}
190#endif 192#endif
191 193
192static void iommu_dev_setup_iSeries(struct pci_dev *dev) { }
193static void iommu_bus_setup_iSeries(struct pci_bus *bus) { }
194
195void iommu_init_early_iSeries(void) 194void iommu_init_early_iSeries(void)
196{ 195{
197 ppc_md.tce_build = tce_build_iSeries; 196 ppc_md.tce_build = tce_build_iSeries;
198 ppc_md.tce_free = tce_free_iSeries; 197 ppc_md.tce_free = tce_free_iSeries;
199 198
200 ppc_md.iommu_dev_setup = iommu_dev_setup_iSeries; 199 pci_dma_ops = &dma_iommu_ops;
201 ppc_md.iommu_bus_setup = iommu_bus_setup_iSeries;
202
203 pci_iommu_init();
204} 200}
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c
index 4aa165e010d9..a90ae42a7bc2 100644
--- a/arch/powerpc/platforms/iseries/pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -253,7 +253,7 @@ void __init iSeries_pci_final_fixup(void)
253 PCI_DN(node)->pcidev = pdev; 253 PCI_DN(node)->pcidev = pdev;
254 allocate_device_bars(pdev); 254 allocate_device_bars(pdev);
255 iSeries_Device_Information(pdev, DeviceCount); 255 iSeries_Device_Information(pdev, DeviceCount);
256 iommu_devnode_init_iSeries(node); 256 iommu_devnode_init_iSeries(pdev, node);
257 } else 257 } else
258 printk("PCI: Device Tree not found for 0x%016lX\n", 258 printk("PCI: Device Tree not found for 0x%016lX\n",
259 (unsigned long)pdev); 259 (unsigned long)pdev);
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
index eb2457567f8a..89d6e295dbf7 100644
--- a/arch/powerpc/platforms/pasemi/setup.c
+++ b/arch/powerpc/platforms/pasemi/setup.c
@@ -26,6 +26,7 @@
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include <linux/console.h> 28#include <linux/console.h>
29#include <linux/pci.h>
29 30
30#include <asm/prom.h> 31#include <asm/prom.h>
31#include <asm/system.h> 32#include <asm/system.h>
@@ -71,6 +72,9 @@ void __init pas_setup_arch(void)
71 /* Setup SMP callback */ 72 /* Setup SMP callback */
72 smp_ops = &pas_smp_ops; 73 smp_ops = &pas_smp_ops;
73#endif 74#endif
75 /* no iommu yet */
76 pci_dma_ops = &dma_direct_ops;
77
74 /* Lookup PCI hosts */ 78 /* Lookup PCI hosts */
75 pas_pci_init(); 79 pas_pci_init();
76 80
@@ -81,17 +85,6 @@ void __init pas_setup_arch(void)
81 printk(KERN_DEBUG "Using default idle loop\n"); 85 printk(KERN_DEBUG "Using default idle loop\n");
82} 86}
83 87
84static void iommu_dev_setup_null(struct pci_dev *dev) { }
85static void iommu_bus_setup_null(struct pci_bus *bus) { }
86
87static void __init pas_init_early(void)
88{
89 /* No iommu code yet */
90 ppc_md.iommu_dev_setup = iommu_dev_setup_null;
91 ppc_md.iommu_bus_setup = iommu_bus_setup_null;
92 pci_direct_iommu_init();
93}
94
95/* No legacy IO on our parts */ 88/* No legacy IO on our parts */
96static int pas_check_legacy_ioport(unsigned int baseport) 89static int pas_check_legacy_ioport(unsigned int baseport)
97{ 90{
@@ -173,7 +166,6 @@ define_machine(pas) {
173 .name = "PA Semi PA6T-1682M", 166 .name = "PA Semi PA6T-1682M",
174 .probe = pas_probe, 167 .probe = pas_probe,
175 .setup_arch = pas_setup_arch, 168 .setup_arch = pas_setup_arch,
176 .init_early = pas_init_early,
177 .init_IRQ = pas_init_IRQ, 169 .init_IRQ = pas_init_IRQ,
178 .get_irq = mpic_get_irq, 170 .get_irq = mpic_get_irq,
179 .restart = pas_restart, 171 .restart = pas_restart,
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 556c279a789d..3c95392f4f41 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -309,7 +309,7 @@ static void iommu_table_setparms_lpar(struct pci_controller *phb,
309 tbl->it_size = size >> IOMMU_PAGE_SHIFT; 309 tbl->it_size = size >> IOMMU_PAGE_SHIFT;
310} 310}
311 311
312static void iommu_bus_setup_pSeries(struct pci_bus *bus) 312static void pci_dma_bus_setup_pSeries(struct pci_bus *bus)
313{ 313{
314 struct device_node *dn; 314 struct device_node *dn;
315 struct iommu_table *tbl; 315 struct iommu_table *tbl;
@@ -318,10 +318,9 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus)
318 struct pci_dn *pci; 318 struct pci_dn *pci;
319 int children; 319 int children;
320 320
321 DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self);
322
323 dn = pci_bus_to_OF_node(bus); 321 dn = pci_bus_to_OF_node(bus);
324 pci = PCI_DN(dn); 322
323 DBG("pci_dma_bus_setup_pSeries: setting up bus %s\n", dn->full_name);
325 324
326 if (bus->self) { 325 if (bus->self) {
327 /* This is not a root bus, any setup will be done for the 326 /* This is not a root bus, any setup will be done for the
@@ -329,6 +328,7 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus)
329 */ 328 */
330 return; 329 return;
331 } 330 }
331 pci = PCI_DN(dn);
332 332
333 /* Check if the ISA bus on the system is under 333 /* Check if the ISA bus on the system is under
334 * this PHB. 334 * this PHB.
@@ -390,17 +390,17 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus)
390} 390}
391 391
392 392
393static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus) 393static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus)
394{ 394{
395 struct iommu_table *tbl; 395 struct iommu_table *tbl;
396 struct device_node *dn, *pdn; 396 struct device_node *dn, *pdn;
397 struct pci_dn *ppci; 397 struct pci_dn *ppci;
398 const void *dma_window = NULL; 398 const void *dma_window = NULL;
399 399
400 DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self);
401
402 dn = pci_bus_to_OF_node(bus); 400 dn = pci_bus_to_OF_node(bus);
403 401
402 DBG("pci_dma_bus_setup_pSeriesLP: setting up bus %s\n", dn->full_name);
403
404 /* Find nearest ibm,dma-window, walking up the device tree */ 404 /* Find nearest ibm,dma-window, walking up the device tree */
405 for (pdn = dn; pdn != NULL; pdn = pdn->parent) { 405 for (pdn = dn; pdn != NULL; pdn = pdn->parent) {
406 dma_window = get_property(pdn, "ibm,dma-window", NULL); 406 dma_window = get_property(pdn, "ibm,dma-window", NULL);
@@ -409,11 +409,15 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
409 } 409 }
410 410
411 if (dma_window == NULL) { 411 if (dma_window == NULL) {
412 DBG("iommu_bus_setup_pSeriesLP: bus %s seems to have no ibm,dma-window property\n", dn->full_name); 412 DBG(" no ibm,dma-window property !\n");
413 return; 413 return;
414 } 414 }
415 415
416 ppci = PCI_DN(pdn); 416 ppci = PCI_DN(pdn);
417
418 DBG(" parent is %s, iommu_table: 0x%p\n",
419 pdn->full_name, ppci->iommu_table);
420
417 if (!ppci->iommu_table) { 421 if (!ppci->iommu_table) {
418 /* Bussubno hasn't been copied yet. 422 /* Bussubno hasn't been copied yet.
419 * Do it now because iommu_table_setparms_lpar needs it. 423 * Do it now because iommu_table_setparms_lpar needs it.
@@ -427,6 +431,7 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
427 iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window); 431 iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window);
428 432
429 ppci->iommu_table = iommu_init_table(tbl, ppci->phb->node); 433 ppci->iommu_table = iommu_init_table(tbl, ppci->phb->node);
434 DBG(" created table: %p\n", ppci->iommu_table);
430 } 435 }
431 436
432 if (pdn != dn) 437 if (pdn != dn)
@@ -434,27 +439,27 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
434} 439}
435 440
436 441
437static void iommu_dev_setup_pSeries(struct pci_dev *dev) 442static void pci_dma_dev_setup_pSeries(struct pci_dev *dev)
438{ 443{
439 struct device_node *dn, *mydn; 444 struct device_node *dn;
440 struct iommu_table *tbl; 445 struct iommu_table *tbl;
441 446
442 DBG("iommu_dev_setup_pSeries, dev %p (%s)\n", dev, pci_name(dev)); 447 DBG("pci_dma_dev_setup_pSeries: %s\n", pci_name(dev));
443 448
444 mydn = dn = pci_device_to_OF_node(dev); 449 dn = dev->dev.archdata.of_node;
445 450
446 /* If we're the direct child of a root bus, then we need to allocate 451 /* If we're the direct child of a root bus, then we need to allocate
447 * an iommu table ourselves. The bus setup code should have setup 452 * an iommu table ourselves. The bus setup code should have setup
448 * the window sizes already. 453 * the window sizes already.
449 */ 454 */
450 if (!dev->bus->self) { 455 if (!dev->bus->self) {
456 struct pci_controller *phb = PCI_DN(dn)->phb;
457
451 DBG(" --> first child, no bridge. Allocating iommu table.\n"); 458 DBG(" --> first child, no bridge. Allocating iommu table.\n");
452 tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, 459 tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
453 PCI_DN(dn)->phb->node); 460 phb->node);
454 iommu_table_setparms(PCI_DN(dn)->phb, dn, tbl); 461 iommu_table_setparms(phb, dn, tbl);
455 PCI_DN(dn)->iommu_table = iommu_init_table(tbl, 462 dev->dev.archdata.dma_data = iommu_init_table(tbl, phb->node);
456 PCI_DN(dn)->phb->node);
457
458 return; 463 return;
459 } 464 }
460 465
@@ -465,11 +470,11 @@ static void iommu_dev_setup_pSeries(struct pci_dev *dev)
465 while (dn && PCI_DN(dn) && PCI_DN(dn)->iommu_table == NULL) 470 while (dn && PCI_DN(dn) && PCI_DN(dn)->iommu_table == NULL)
466 dn = dn->parent; 471 dn = dn->parent;
467 472
468 if (dn && PCI_DN(dn)) { 473 if (dn && PCI_DN(dn))
469 PCI_DN(mydn)->iommu_table = PCI_DN(dn)->iommu_table; 474 dev->dev.archdata.dma_data = PCI_DN(dn)->iommu_table;
470 } else { 475 else
471 DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, pci_name(dev)); 476 printk(KERN_WARNING "iommu: Device %s has no iommu table\n",
472 } 477 pci_name(dev));
473} 478}
474 479
475static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node) 480static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node)
@@ -495,13 +500,15 @@ static struct notifier_block iommu_reconfig_nb = {
495 .notifier_call = iommu_reconfig_notifier, 500 .notifier_call = iommu_reconfig_notifier,
496}; 501};
497 502
498static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) 503static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
499{ 504{
500 struct device_node *pdn, *dn; 505 struct device_node *pdn, *dn;
501 struct iommu_table *tbl; 506 struct iommu_table *tbl;
502 const void *dma_window = NULL; 507 const void *dma_window = NULL;
503 struct pci_dn *pci; 508 struct pci_dn *pci;
504 509
510 DBG("pci_dma_dev_setup_pSeriesLP: %s\n", pci_name(dev));
511
505 /* dev setup for LPAR is a little tricky, since the device tree might 512 /* dev setup for LPAR is a little tricky, since the device tree might
506 * contain the dma-window properties per-device and not neccesarily 513 * contain the dma-window properties per-device and not neccesarily
507 * for the bus. So we need to search upwards in the tree until we 514 * for the bus. So we need to search upwards in the tree until we
@@ -509,9 +516,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
509 * already allocated. 516 * already allocated.
510 */ 517 */
511 dn = pci_device_to_OF_node(dev); 518 dn = pci_device_to_OF_node(dev);
512 519 DBG(" node is %s\n", dn->full_name);
513 DBG("iommu_dev_setup_pSeriesLP, dev %p (%s) %s\n",
514 dev, pci_name(dev), dn->full_name);
515 520
516 for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table; 521 for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table;
517 pdn = pdn->parent) { 522 pdn = pdn->parent) {
@@ -520,16 +525,17 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
520 break; 525 break;
521 } 526 }
522 527
528 DBG(" parent is %s\n", pdn->full_name);
529
523 /* Check for parent == NULL so we don't try to setup the empty EADS 530 /* Check for parent == NULL so we don't try to setup the empty EADS
524 * slots on POWER4 machines. 531 * slots on POWER4 machines.
525 */ 532 */
526 if (dma_window == NULL || pdn->parent == NULL) { 533 if (dma_window == NULL || pdn->parent == NULL) {
527 DBG("No dma window for device, linking to parent\n"); 534 DBG(" no dma window for device, linking to parent\n");
528 PCI_DN(dn)->iommu_table = PCI_DN(pdn)->iommu_table; 535 dev->dev.archdata.dma_data = PCI_DN(pdn)->iommu_table;
529 return; 536 return;
530 } else {
531 DBG("Found DMA window, allocating table\n");
532 } 537 }
538 DBG(" found DMA window, table: %p\n", pci->iommu_table);
533 539
534 pci = PCI_DN(pdn); 540 pci = PCI_DN(pdn);
535 if (!pci->iommu_table) { 541 if (!pci->iommu_table) {
@@ -542,24 +548,20 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
542 iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window); 548 iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window);
543 549
544 pci->iommu_table = iommu_init_table(tbl, pci->phb->node); 550 pci->iommu_table = iommu_init_table(tbl, pci->phb->node);
551 DBG(" created table: %p\n", pci->iommu_table);
545 } 552 }
546 553
547 if (pdn != dn) 554 dev->dev.archdata.dma_data = pci->iommu_table;
548 PCI_DN(dn)->iommu_table = pci->iommu_table;
549} 555}
550 556
551static void iommu_bus_setup_null(struct pci_bus *b) { }
552static void iommu_dev_setup_null(struct pci_dev *d) { }
553
554/* These are called very early. */ 557/* These are called very early. */
555void iommu_init_early_pSeries(void) 558void iommu_init_early_pSeries(void)
556{ 559{
557 if (of_chosen && get_property(of_chosen, "linux,iommu-off", NULL)) { 560 if (of_chosen && get_property(of_chosen, "linux,iommu-off", NULL)) {
558 /* Direct I/O, IOMMU off */ 561 /* Direct I/O, IOMMU off */
559 ppc_md.iommu_dev_setup = iommu_dev_setup_null; 562 ppc_md.pci_dma_dev_setup = NULL;
560 ppc_md.iommu_bus_setup = iommu_bus_setup_null; 563 ppc_md.pci_dma_bus_setup = NULL;
561 pci_direct_iommu_init(); 564 pci_dma_ops = &dma_direct_ops;
562
563 return; 565 return;
564 } 566 }
565 567
@@ -572,19 +574,19 @@ void iommu_init_early_pSeries(void)
572 ppc_md.tce_free = tce_free_pSeriesLP; 574 ppc_md.tce_free = tce_free_pSeriesLP;
573 } 575 }
574 ppc_md.tce_get = tce_get_pSeriesLP; 576 ppc_md.tce_get = tce_get_pSeriesLP;
575 ppc_md.iommu_bus_setup = iommu_bus_setup_pSeriesLP; 577 ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_pSeriesLP;
576 ppc_md.iommu_dev_setup = iommu_dev_setup_pSeriesLP; 578 ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_pSeriesLP;
577 } else { 579 } else {
578 ppc_md.tce_build = tce_build_pSeries; 580 ppc_md.tce_build = tce_build_pSeries;
579 ppc_md.tce_free = tce_free_pSeries; 581 ppc_md.tce_free = tce_free_pSeries;
580 ppc_md.tce_get = tce_get_pseries; 582 ppc_md.tce_get = tce_get_pseries;
581 ppc_md.iommu_bus_setup = iommu_bus_setup_pSeries; 583 ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_pSeries;
582 ppc_md.iommu_dev_setup = iommu_dev_setup_pSeries; 584 ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_pSeries;
583 } 585 }
584 586
585 587
586 pSeries_reconfig_notifier_register(&iommu_reconfig_nb); 588 pSeries_reconfig_notifier_register(&iommu_reconfig_nb);
587 589
588 pci_iommu_init(); 590 pci_dma_ops = &dma_iommu_ops;
589} 591}
590 592
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index 6bfacc217085..bb0cb5c5b565 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -93,8 +93,8 @@ pcibios_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
93 if (list_empty(&dev->global_list)) { 93 if (list_empty(&dev->global_list)) {
94 int i; 94 int i;
95 95
96 /* Need to setup IOMMU tables */ 96 /* Fill device archdata and setup iommu table */
97 ppc_md.iommu_dev_setup(dev); 97 pcibios_setup_new_device(dev);
98 98
99 if(fix_bus) 99 if(fix_bus)
100 pcibios_fixup_device_resources(dev, bus); 100 pcibios_fixup_device_resources(dev, bus);
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index 572b7846cc77..ac784bb57289 100644
--- a/arch/powerpc/sysdev/dart_iommu.c
+++ b/arch/powerpc/sysdev/dart_iommu.c
@@ -289,24 +289,15 @@ static void iommu_table_dart_setup(void)
289 set_bit(iommu_table_dart.it_size - 1, iommu_table_dart.it_map); 289 set_bit(iommu_table_dart.it_size - 1, iommu_table_dart.it_map);
290} 290}
291 291
292static void iommu_dev_setup_dart(struct pci_dev *dev) 292static void pci_dma_dev_setup_dart(struct pci_dev *dev)
293{ 293{
294 struct device_node *dn;
295
296 /* We only have one iommu table on the mac for now, which makes 294 /* We only have one iommu table on the mac for now, which makes
297 * things simple. Setup all PCI devices to point to this table 295 * things simple. Setup all PCI devices to point to this table
298 *
299 * We must use pci_device_to_OF_node() to make sure that
300 * we get the real "final" pointer to the device in the
301 * pci_dev sysdata and not the temporary PHB one
302 */ 296 */
303 dn = pci_device_to_OF_node(dev); 297 dev->dev.archdata.dma_data = &iommu_table_dart;
304
305 if (dn)
306 PCI_DN(dn)->iommu_table = &iommu_table_dart;
307} 298}
308 299
309static void iommu_bus_setup_dart(struct pci_bus *bus) 300static void pci_dma_bus_setup_dart(struct pci_bus *bus)
310{ 301{
311 struct device_node *dn; 302 struct device_node *dn;
312 303
@@ -321,9 +312,6 @@ static void iommu_bus_setup_dart(struct pci_bus *bus)
321 PCI_DN(dn)->iommu_table = &iommu_table_dart; 312 PCI_DN(dn)->iommu_table = &iommu_table_dart;
322} 313}
323 314
324static void iommu_dev_setup_null(struct pci_dev *dev) { }
325static void iommu_bus_setup_null(struct pci_bus *bus) { }
326
327void iommu_init_early_dart(void) 315void iommu_init_early_dart(void)
328{ 316{
329 struct device_node *dn; 317 struct device_node *dn;
@@ -344,22 +332,21 @@ void iommu_init_early_dart(void)
344 332
345 /* Initialize the DART HW */ 333 /* Initialize the DART HW */
346 if (dart_init(dn) == 0) { 334 if (dart_init(dn) == 0) {
347 ppc_md.iommu_dev_setup = iommu_dev_setup_dart; 335 ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_dart;
348 ppc_md.iommu_bus_setup = iommu_bus_setup_dart; 336 ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_dart;
349 337
350 /* Setup pci_dma ops */ 338 /* Setup pci_dma ops */
351 pci_iommu_init(); 339 pci_dma_ops = &dma_iommu_ops;
352
353 return; 340 return;
354 } 341 }
355 342
356 bail: 343 bail:
357 /* If init failed, use direct iommu and null setup functions */ 344 /* If init failed, use direct iommu and null setup functions */
358 ppc_md.iommu_dev_setup = iommu_dev_setup_null; 345 ppc_md.pci_dma_dev_setup = NULL;
359 ppc_md.iommu_bus_setup = iommu_bus_setup_null; 346 ppc_md.pci_dma_bus_setup = NULL;
360 347
361 /* Setup pci_dma ops */ 348 /* Setup pci_dma ops */
362 pci_direct_iommu_init(); 349 pci_dma_ops = &dma_direct_ops;
363} 350}
364 351
365 352
diff --git a/include/asm-powerpc/device.h b/include/asm-powerpc/device.h
index d8f9872b0e2d..228ab2a315b9 100644
--- a/include/asm-powerpc/device.h
+++ b/include/asm-powerpc/device.h
@@ -3,5 +3,22 @@
3 * 3 *
4 * This file is released under the GPLv2 4 * This file is released under the GPLv2
5 */ 5 */
6#include <asm-generic/device.h> 6#ifndef _ASM_POWERPC_DEVICE_H
7#define _ASM_POWERPC_DEVICE_H
7 8
9struct dma_mapping_ops;
10struct device_node;
11
12struct dev_archdata {
13 /* Optional pointer to an OF device node */
14 struct device_node *of_node;
15
16 /* DMA operations on that device */
17 struct dma_mapping_ops *dma_ops;
18 void *dma_data;
19
20 /* NUMA node if applicable */
21 int numa_node;
22};
23
24#endif /* _ASM_POWERPC_DEVICE_H */
diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h
index 2ab9baf78bb4..8367810c994c 100644
--- a/include/asm-powerpc/dma-mapping.h
+++ b/include/asm-powerpc/dma-mapping.h
@@ -44,26 +44,148 @@ extern void __dma_sync_page(struct page *page, unsigned long offset,
44#endif /* ! CONFIG_NOT_COHERENT_CACHE */ 44#endif /* ! CONFIG_NOT_COHERENT_CACHE */
45 45
46#ifdef CONFIG_PPC64 46#ifdef CONFIG_PPC64
47/*
48 * DMA operations are abstracted for G5 vs. i/pSeries, PCI vs. VIO
49 */
50struct dma_mapping_ops {
51 void * (*alloc_coherent)(struct device *dev, size_t size,
52 dma_addr_t *dma_handle, gfp_t flag);
53 void (*free_coherent)(struct device *dev, size_t size,
54 void *vaddr, dma_addr_t dma_handle);
55 dma_addr_t (*map_single)(struct device *dev, void *ptr,
56 size_t size, enum dma_data_direction direction);
57 void (*unmap_single)(struct device *dev, dma_addr_t dma_addr,
58 size_t size, enum dma_data_direction direction);
59 int (*map_sg)(struct device *dev, struct scatterlist *sg,
60 int nents, enum dma_data_direction direction);
61 void (*unmap_sg)(struct device *dev, struct scatterlist *sg,
62 int nents, enum dma_data_direction direction);
63 int (*dma_supported)(struct device *dev, u64 mask);
64 int (*dac_dma_supported)(struct device *dev, u64 mask);
65 int (*set_dma_mask)(struct device *dev, u64 dma_mask);
66};
67
68static inline struct dma_mapping_ops *get_dma_ops(struct device *dev)
69{
70 /* We don't handle the NULL dev case for ISA for now. We could
71 * do it via an out of line call but it is not needed for now. The
72 * only ISA DMA device we support is the floppy and we have a hack
73 * in the floppy driver directly to get a device for us.
74 */
75 if (unlikely(dev == NULL || dev->archdata.dma_ops == NULL))
76 return NULL;
77 return dev->archdata.dma_ops;
78}
79
80static inline int dma_supported(struct device *dev, u64 mask)
81{
82 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
83
84 if (unlikely(dma_ops == NULL))
85 return 0;
86 if (dma_ops->dma_supported == NULL)
87 return 1;
88 return dma_ops->dma_supported(dev, mask);
89}
90
91static inline int dma_set_mask(struct device *dev, u64 dma_mask)
92{
93 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
94
95 if (unlikely(dma_ops == NULL))
96 return -EIO;
97 if (dma_ops->set_dma_mask != NULL)
98 return dma_ops->set_dma_mask(dev, dma_mask);
99 if (!dev->dma_mask || !dma_supported(dev, *dev->dma_mask))
100 return -EIO;
101 *dev->dma_mask = dma_mask;
102 return 0;
103}
104
105static inline void *dma_alloc_coherent(struct device *dev, size_t size,
106 dma_addr_t *dma_handle, gfp_t flag)
107{
108 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
109
110 BUG_ON(!dma_ops);
111 return dma_ops->alloc_coherent(dev, size, dma_handle, flag);
112}
113
114static inline void dma_free_coherent(struct device *dev, size_t size,
115 void *cpu_addr, dma_addr_t dma_handle)
116{
117 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
118
119 BUG_ON(!dma_ops);
120 dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
121}
122
123static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
124 size_t size,
125 enum dma_data_direction direction)
126{
127 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
128
129 BUG_ON(!dma_ops);
130 return dma_ops->map_single(dev, cpu_addr, size, direction);
131}
132
133static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
134 size_t size,
135 enum dma_data_direction direction)
136{
137 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
138
139 BUG_ON(!dma_ops);
140 dma_ops->unmap_single(dev, dma_addr, size, direction);
141}
142
143static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
144 unsigned long offset, size_t size,
145 enum dma_data_direction direction)
146{
147 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
148
149 BUG_ON(!dma_ops);
150 return dma_ops->map_single(dev, page_address(page) + offset, size,
151 direction);
152}
153
154static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
155 size_t size,
156 enum dma_data_direction direction)
157{
158 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
159
160 BUG_ON(!dma_ops);
161 dma_ops->unmap_single(dev, dma_address, size, direction);
162}
163
164static inline int dma_map_sg(struct device *dev, struct scatterlist *sg,
165 int nents, enum dma_data_direction direction)
166{
167 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
168
169 BUG_ON(!dma_ops);
170 return dma_ops->map_sg(dev, sg, nents, direction);
171}
172
173static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
174 int nhwentries,
175 enum dma_data_direction direction)
176{
177 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
178
179 BUG_ON(!dma_ops);
180 dma_ops->unmap_sg(dev, sg, nhwentries, direction);
181}
47 182
48extern int dma_supported(struct device *dev, u64 mask); 183
49extern int dma_set_mask(struct device *dev, u64 dma_mask); 184/*
50extern void *dma_alloc_coherent(struct device *dev, size_t size, 185 * Available generic sets of operations
51 dma_addr_t *dma_handle, gfp_t flag); 186 */
52extern void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, 187extern struct dma_mapping_ops dma_iommu_ops;
53 dma_addr_t dma_handle); 188extern struct dma_mapping_ops dma_direct_ops;
54extern dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
55 size_t size, enum dma_data_direction direction);
56extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
57 size_t size, enum dma_data_direction direction);
58extern dma_addr_t dma_map_page(struct device *dev, struct page *page,
59 unsigned long offset, size_t size,
60 enum dma_data_direction direction);
61extern void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
62 size_t size, enum dma_data_direction direction);
63extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
64 enum dma_data_direction direction);
65extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
66 int nhwentries, enum dma_data_direction direction);
67 189
68#else /* CONFIG_PPC64 */ 190#else /* CONFIG_PPC64 */
69 191
@@ -261,25 +383,5 @@ static inline void dma_cache_sync(void *vaddr, size_t size,
261 __dma_sync(vaddr, size, (int)direction); 383 __dma_sync(vaddr, size, (int)direction);
262} 384}
263 385
264/*
265 * DMA operations are abstracted for G5 vs. i/pSeries, PCI vs. VIO
266 */
267struct dma_mapping_ops {
268 void * (*alloc_coherent)(struct device *dev, size_t size,
269 dma_addr_t *dma_handle, gfp_t flag);
270 void (*free_coherent)(struct device *dev, size_t size,
271 void *vaddr, dma_addr_t dma_handle);
272 dma_addr_t (*map_single)(struct device *dev, void *ptr,
273 size_t size, enum dma_data_direction direction);
274 void (*unmap_single)(struct device *dev, dma_addr_t dma_addr,
275 size_t size, enum dma_data_direction direction);
276 int (*map_sg)(struct device *dev, struct scatterlist *sg,
277 int nents, enum dma_data_direction direction);
278 void (*unmap_sg)(struct device *dev, struct scatterlist *sg,
279 int nents, enum dma_data_direction direction);
280 int (*dma_supported)(struct device *dev, u64 mask);
281 int (*dac_dma_supported)(struct device *dev, u64 mask);
282};
283
284#endif /* __KERNEL__ */ 386#endif /* __KERNEL__ */
285#endif /* _ASM_DMA_MAPPING_H */ 387#endif /* _ASM_DMA_MAPPING_H */
diff --git a/include/asm-powerpc/ibmebus.h b/include/asm-powerpc/ibmebus.h
index 3493429b70f5..66112114b8c5 100644
--- a/include/asm-powerpc/ibmebus.h
+++ b/include/asm-powerpc/ibmebus.h
@@ -44,7 +44,6 @@
44#include <linux/mod_devicetable.h> 44#include <linux/mod_devicetable.h>
45#include <asm/of_device.h> 45#include <asm/of_device.h>
46 46
47extern struct dma_mapping_ops ibmebus_dma_ops;
48extern struct bus_type ibmebus_bus_type; 47extern struct bus_type ibmebus_bus_type;
49 48
50struct ibmebus_dev { 49struct ibmebus_dev {
diff --git a/include/asm-powerpc/iommu.h b/include/asm-powerpc/iommu.h
index 19e6f7e0a607..19403183dbbc 100644
--- a/include/asm-powerpc/iommu.h
+++ b/include/asm-powerpc/iommu.h
@@ -79,22 +79,22 @@ extern void iommu_free_table(struct device_node *dn);
79extern struct iommu_table *iommu_init_table(struct iommu_table * tbl, 79extern struct iommu_table *iommu_init_table(struct iommu_table * tbl,
80 int nid); 80 int nid);
81 81
82extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl, 82extern int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
83 struct scatterlist *sglist, int nelems, unsigned long mask, 83 int nelems, unsigned long mask,
84 enum dma_data_direction direction); 84 enum dma_data_direction direction);
85extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, 85extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
86 int nelems, enum dma_data_direction direction); 86 int nelems, enum dma_data_direction direction);
87 87
88extern void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, 88extern void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size,
89 dma_addr_t *dma_handle, unsigned long mask, 89 dma_addr_t *dma_handle, unsigned long mask,
90 gfp_t flag, int node); 90 gfp_t flag, int node);
91extern void iommu_free_coherent(struct iommu_table *tbl, size_t size, 91extern void iommu_free_coherent(struct iommu_table *tbl, size_t size,
92 void *vaddr, dma_addr_t dma_handle); 92 void *vaddr, dma_addr_t dma_handle);
93extern dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, 93extern dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr,
94 size_t size, unsigned long mask, 94 size_t size, unsigned long mask,
95 enum dma_data_direction direction); 95 enum dma_data_direction direction);
96extern void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle, 96extern void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle,
97 size_t size, enum dma_data_direction direction); 97 size_t size, enum dma_data_direction direction);
98 98
99extern void iommu_init_early_pSeries(void); 99extern void iommu_init_early_pSeries(void);
100extern void iommu_init_early_iSeries(void); 100extern void iommu_init_early_iSeries(void);
diff --git a/include/asm-powerpc/iseries/iommu.h b/include/asm-powerpc/iseries/iommu.h
index 0edbfe10cb37..6e323a13ac30 100644
--- a/include/asm-powerpc/iseries/iommu.h
+++ b/include/asm-powerpc/iseries/iommu.h
@@ -21,11 +21,13 @@
21 * Boston, MA 02111-1307 USA 21 * Boston, MA 02111-1307 USA
22 */ 22 */
23 23
24struct pci_dev;
24struct device_node; 25struct device_node;
25struct iommu_table; 26struct iommu_table;
26 27
27/* Creates table for an individual device node */ 28/* Creates table for an individual device node */
28extern void iommu_devnode_init_iSeries(struct device_node *dn); 29extern void iommu_devnode_init_iSeries(struct pci_dev *pdev,
30 struct device_node *dn);
29 31
30/* Get table parameters from HV */ 32/* Get table parameters from HV */
31extern void iommu_table_getparms_iSeries(unsigned long busno, 33extern void iommu_table_getparms_iSeries(unsigned long busno,
diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h
index 162205f62641..ccc29744656e 100644
--- a/include/asm-powerpc/machdep.h
+++ b/include/asm-powerpc/machdep.h
@@ -84,8 +84,8 @@ struct machdep_calls {
84 unsigned long (*tce_get)(struct iommu_table *tbl, 84 unsigned long (*tce_get)(struct iommu_table *tbl,
85 long index); 85 long index);
86 void (*tce_flush)(struct iommu_table *tbl); 86 void (*tce_flush)(struct iommu_table *tbl);
87 void (*iommu_dev_setup)(struct pci_dev *dev); 87 void (*pci_dma_dev_setup)(struct pci_dev *dev);
88 void (*iommu_bus_setup)(struct pci_bus *bus); 88 void (*pci_dma_bus_setup)(struct pci_bus *bus);
89#endif /* CONFIG_PPC64 */ 89#endif /* CONFIG_PPC64 */
90 90
91 int (*probe)(void); 91 int (*probe)(void);
diff --git a/include/asm-powerpc/of_device.h b/include/asm-powerpc/of_device.h
index 1ef7e9edd1a7..a889b2005bf5 100644
--- a/include/asm-powerpc/of_device.h
+++ b/include/asm-powerpc/of_device.h
@@ -14,7 +14,7 @@
14 */ 14 */
15struct of_device 15struct of_device
16{ 16{
17 struct device_node *node; /* OF device node */ 17 struct device_node *node; /* to be obsoleted */
18 u64 dma_mask; /* DMA mask */ 18 u64 dma_mask; /* DMA mask */
19 struct device dev; /* Generic device interface */ 19 struct device dev; /* Generic device interface */
20}; 20};
diff --git a/include/asm-powerpc/pci.h b/include/asm-powerpc/pci.h
index c77286051496..16f13319c769 100644
--- a/include/asm-powerpc/pci.h
+++ b/include/asm-powerpc/pci.h
@@ -70,15 +70,15 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
70 */ 70 */
71#define PCI_DISABLE_MWI 71#define PCI_DISABLE_MWI
72 72
73extern struct dma_mapping_ops pci_dma_ops; 73extern struct dma_mapping_ops *pci_dma_ops;
74 74
75/* For DAC DMA, we currently don't support it by default, but 75/* For DAC DMA, we currently don't support it by default, but
76 * we let 64-bit platforms override this. 76 * we let 64-bit platforms override this.
77 */ 77 */
78static inline int pci_dac_dma_supported(struct pci_dev *hwdev,u64 mask) 78static inline int pci_dac_dma_supported(struct pci_dev *hwdev,u64 mask)
79{ 79{
80 if (pci_dma_ops.dac_dma_supported) 80 if (pci_dma_ops && pci_dma_ops->dac_dma_supported)
81 return pci_dma_ops.dac_dma_supported(&hwdev->dev, mask); 81 return pci_dma_ops->dac_dma_supported(&hwdev->dev, mask);
82 return 0; 82 return 0;
83} 83}
84 84
@@ -210,6 +210,8 @@ extern int remap_bus_range(struct pci_bus *bus);
210extern void pcibios_fixup_device_resources(struct pci_dev *dev, 210extern void pcibios_fixup_device_resources(struct pci_dev *dev,
211 struct pci_bus *bus); 211 struct pci_bus *bus);
212 212
213extern void pcibios_setup_new_device(struct pci_dev *dev);
214
213extern void pcibios_claim_one_bus(struct pci_bus *b); 215extern void pcibios_claim_one_bus(struct pci_bus *b);
214 216
215extern struct pci_controller *init_phb_dynamic(struct device_node *dn); 217extern struct pci_controller *init_phb_dynamic(struct device_node *dn);
diff --git a/include/asm-powerpc/vio.h b/include/asm-powerpc/vio.h
index 4b51d42e1419..0117b544ecbc 100644
--- a/include/asm-powerpc/vio.h
+++ b/include/asm-powerpc/vio.h
@@ -45,7 +45,6 @@ struct iommu_table;
45 * The vio_dev structure is used to describe virtual I/O devices. 45 * The vio_dev structure is used to describe virtual I/O devices.
46 */ 46 */
47struct vio_dev { 47struct vio_dev {
48 struct iommu_table *iommu_table; /* vio_map_* uses this */
49 const char *name; 48 const char *name;
50 const char *type; 49 const char *type;
51 uint32_t unit_address; 50 uint32_t unit_address;