diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/kernel/vio.c | 78 | ||||
-rw-r--r-- | arch/powerpc/platforms/iseries/iommu.c | 24 |
2 files changed, 48 insertions, 54 deletions
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index eaf7f6992a2f..b7c9e44ef180 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c | |||
@@ -48,61 +48,33 @@ static struct vio_dev vio_bus_device = { /* fake "parent" device */ | |||
48 | .dev.bus = &vio_bus_type, | 48 | .dev.bus = &vio_bus_type, |
49 | }; | 49 | }; |
50 | 50 | ||
51 | #ifdef CONFIG_PPC_ISERIES | ||
52 | static struct iommu_table veth_iommu_table; | ||
53 | struct iommu_table vio_iommu_table; | ||
54 | |||
55 | static void __init iommu_vio_init(void) | ||
56 | { | ||
57 | iommu_table_getparms_iSeries(255, 0, 0xff, &veth_iommu_table); | ||
58 | veth_iommu_table.it_size /= 2; | ||
59 | vio_iommu_table = veth_iommu_table; | ||
60 | vio_iommu_table.it_offset += veth_iommu_table.it_size; | ||
61 | |||
62 | if (!iommu_init_table(&veth_iommu_table, -1)) | ||
63 | printk("Virtual Bus VETH TCE table failed.\n"); | ||
64 | if (!iommu_init_table(&vio_iommu_table, -1)) | ||
65 | printk("Virtual Bus VIO TCE table failed.\n"); | ||
66 | } | ||
67 | #else | ||
68 | static void __init iommu_vio_init(void) | ||
69 | { | ||
70 | } | ||
71 | #endif | ||
72 | |||
73 | static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) | 51 | static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) |
74 | { | 52 | { |
75 | #ifdef CONFIG_PPC_ISERIES | 53 | const unsigned char *dma_window; |
76 | if (firmware_has_feature(FW_FEATURE_ISERIES)) { | 54 | struct iommu_table *tbl; |
77 | if (strcmp(dev->type, "network") == 0) | 55 | unsigned long offset, size; |
78 | return &veth_iommu_table; | 56 | |
79 | return &vio_iommu_table; | 57 | if (firmware_has_feature(FW_FEATURE_ISERIES)) |
80 | } else | 58 | return vio_build_iommu_table_iseries(dev); |
81 | #endif | 59 | |
82 | { | 60 | dma_window = of_get_property(dev->dev.archdata.of_node, |
83 | const unsigned char *dma_window; | 61 | "ibm,my-dma-window", NULL); |
84 | struct iommu_table *tbl; | 62 | if (!dma_window) |
85 | unsigned long offset, size; | 63 | return NULL; |
86 | 64 | ||
87 | dma_window = of_get_property(dev->dev.archdata.of_node, | 65 | tbl = kmalloc(sizeof(*tbl), GFP_KERNEL); |
88 | "ibm,my-dma-window", NULL); | 66 | |
89 | if (!dma_window) | 67 | of_parse_dma_window(dev->dev.archdata.of_node, dma_window, |
90 | return NULL; | 68 | &tbl->it_index, &offset, &size); |
91 | 69 | ||
92 | tbl = kmalloc(sizeof(*tbl), GFP_KERNEL); | 70 | /* TCE table size - measured in tce entries */ |
93 | 71 | tbl->it_size = size >> IOMMU_PAGE_SHIFT; | |
94 | of_parse_dma_window(dev->dev.archdata.of_node, dma_window, | 72 | /* offset for VIO should always be 0 */ |
95 | &tbl->it_index, &offset, &size); | 73 | tbl->it_offset = offset >> IOMMU_PAGE_SHIFT; |
96 | 74 | tbl->it_busno = 0; | |
97 | /* TCE table size - measured in tce entries */ | 75 | tbl->it_type = TCE_VB; |
98 | tbl->it_size = size >> IOMMU_PAGE_SHIFT; | 76 | |
99 | /* offset for VIO should always be 0 */ | 77 | return iommu_init_table(tbl, -1); |
100 | tbl->it_offset = offset >> IOMMU_PAGE_SHIFT; | ||
101 | tbl->it_busno = 0; | ||
102 | tbl->it_type = TCE_VB; | ||
103 | |||
104 | return iommu_init_table(tbl, -1); | ||
105 | } | ||
106 | } | 78 | } |
107 | 79 | ||
108 | /** | 80 | /** |
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index 3281f10bbd16..49e9c664ea89 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | 32 | ||
33 | #include <asm/iommu.h> | 33 | #include <asm/iommu.h> |
34 | #include <asm/vio.h> | ||
34 | #include <asm/tce.h> | 35 | #include <asm/tce.h> |
35 | #include <asm/machdep.h> | 36 | #include <asm/machdep.h> |
36 | #include <asm/abs_addr.h> | 37 | #include <asm/abs_addr.h> |
@@ -191,7 +192,8 @@ void iommu_devnode_init_iSeries(struct pci_dev *pdev, struct device_node *dn) | |||
191 | } | 192 | } |
192 | #endif | 193 | #endif |
193 | 194 | ||
194 | extern struct iommu_table vio_iommu_table; | 195 | static struct iommu_table veth_iommu_table; |
196 | static struct iommu_table vio_iommu_table; | ||
195 | 197 | ||
196 | void *iseries_hv_alloc(size_t size, dma_addr_t *dma_handle, gfp_t flag) | 198 | void *iseries_hv_alloc(size_t size, dma_addr_t *dma_handle, gfp_t flag) |
197 | { | 199 | { |
@@ -219,6 +221,26 @@ void iseries_hv_unmap(dma_addr_t dma_handle, size_t size, | |||
219 | iommu_unmap_single(&vio_iommu_table, dma_handle, size, direction); | 221 | iommu_unmap_single(&vio_iommu_table, dma_handle, size, direction); |
220 | } | 222 | } |
221 | 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 | |||
222 | void iommu_init_early_iSeries(void) | 244 | void iommu_init_early_iSeries(void) |
223 | { | 245 | { |
224 | ppc_md.tce_build = tce_build_iSeries; | 246 | ppc_md.tce_build = tce_build_iSeries; |