aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/vio.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/vio.c')
-rw-r--r--arch/powerpc/kernel/vio.c104
1 files changed, 28 insertions, 76 deletions
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 62c1bc12ea39..cb22a3557c4e 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -39,6 +39,8 @@
39 39
40extern struct kset devices_subsys; /* needed for vio_find_name() */ 40extern struct kset devices_subsys; /* needed for vio_find_name() */
41 41
42static struct bus_type vio_bus_type;
43
42static struct vio_dev vio_bus_device = { /* fake "parent" device */ 44static struct vio_dev vio_bus_device = { /* fake "parent" device */
43 .name = vio_bus_device.dev.bus_id, 45 .name = vio_bus_device.dev.bus_id,
44 .type = "", 46 .type = "",
@@ -46,60 +48,33 @@ static struct vio_dev vio_bus_device = { /* fake "parent" device */
46 .dev.bus = &vio_bus_type, 48 .dev.bus = &vio_bus_type,
47}; 49};
48 50
49#ifdef CONFIG_PPC_ISERIES 51static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
50struct device *iSeries_vio_dev = &vio_bus_device.dev; 52{
51EXPORT_SYMBOL(iSeries_vio_dev); 53 const unsigned char *dma_window;
54 struct iommu_table *tbl;
55 unsigned long offset, size;
52 56
53static struct iommu_table veth_iommu_table; 57 if (firmware_has_feature(FW_FEATURE_ISERIES))
54static struct iommu_table vio_iommu_table; 58 return vio_build_iommu_table_iseries(dev);
55 59
56static void __init iommu_vio_init(void) 60 dma_window = of_get_property(dev->dev.archdata.of_node,
57{ 61 "ibm,my-dma-window", NULL);
58 iommu_table_getparms_iSeries(255, 0, 0xff, &veth_iommu_table); 62 if (!dma_window)
59 veth_iommu_table.it_size /= 2; 63 return NULL;
60 vio_iommu_table = veth_iommu_table;
61 vio_iommu_table.it_offset += veth_iommu_table.it_size;
62
63 if (!iommu_init_table(&veth_iommu_table, -1))
64 printk("Virtual Bus VETH TCE table failed.\n");
65 if (!iommu_init_table(&vio_iommu_table, -1))
66 printk("Virtual Bus VIO TCE table failed.\n");
67}
68#endif
69 64
70static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) 65 tbl = kmalloc(sizeof(*tbl), GFP_KERNEL);
71{ 66
72#ifdef CONFIG_PPC_ISERIES 67 of_parse_dma_window(dev->dev.archdata.of_node, dma_window,
73 if (firmware_has_feature(FW_FEATURE_ISERIES)) { 68 &tbl->it_index, &offset, &size);
74 if (strcmp(dev->type, "network") == 0) 69
75 return &veth_iommu_table; 70 /* TCE table size - measured in tce entries */
76 return &vio_iommu_table; 71 tbl->it_size = size >> IOMMU_PAGE_SHIFT;
77 } else 72 /* offset for VIO should always be 0 */
78#endif 73 tbl->it_offset = offset >> IOMMU_PAGE_SHIFT;
79 { 74 tbl->it_busno = 0;
80 const unsigned char *dma_window; 75 tbl->it_type = TCE_VB;
81 struct iommu_table *tbl; 76
82 unsigned long offset, size; 77 return iommu_init_table(tbl, -1);
83
84 dma_window = of_get_property(dev->dev.archdata.of_node,
85 "ibm,my-dma-window", NULL);
86 if (!dma_window)
87 return NULL;
88
89 tbl = kmalloc(sizeof(*tbl), GFP_KERNEL);
90
91 of_parse_dma_window(dev->dev.archdata.of_node, dma_window,
92 &tbl->it_index, &offset, &size);
93
94 /* TCE table size - measured in tce entries */
95 tbl->it_size = size >> IOMMU_PAGE_SHIFT;
96 /* offset for VIO should always be 0 */
97 tbl->it_offset = offset >> IOMMU_PAGE_SHIFT;
98 tbl->it_busno = 0;
99 tbl->it_type = TCE_VB;
100
101 return iommu_init_table(tbl, -1);
102 }
103} 78}
104 79
105/** 80/**
@@ -160,16 +135,6 @@ static int vio_bus_remove(struct device *dev)
160 return 1; 135 return 1;
161} 136}
162 137
163/* convert from struct device to struct vio_dev and pass to driver. */
164static void vio_bus_shutdown(struct device *dev)
165{
166 struct vio_dev *viodev = to_vio_dev(dev);
167 struct vio_driver *viodrv = to_vio_driver(dev->driver);
168
169 if (dev->driver && viodrv->shutdown)
170 viodrv->shutdown(viodev);
171}
172
173/** 138/**
174 * vio_register_driver: - Register a new vio driver 139 * vio_register_driver: - Register a new vio driver
175 * @drv: The vio_driver structure to be registered. 140 * @drv: The vio_driver structure to be registered.
@@ -282,15 +247,6 @@ static int __init vio_bus_init(void)
282 int err; 247 int err;
283 struct device_node *node_vroot; 248 struct device_node *node_vroot;
284 249
285#ifdef CONFIG_PPC_ISERIES
286 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
287 iommu_vio_init();
288 vio_bus_device.dev.archdata.dma_ops = &dma_iommu_ops;
289 vio_bus_device.dev.archdata.dma_data = &vio_iommu_table;
290 iSeries_vio_dev = &vio_bus_device.dev;
291 }
292#endif /* CONFIG_PPC_ISERIES */
293
294 err = bus_register(&vio_bus_type); 250 err = bus_register(&vio_bus_type);
295 if (err) { 251 if (err) {
296 printk(KERN_ERR "failed to register VIO bus\n"); 252 printk(KERN_ERR "failed to register VIO bus\n");
@@ -317,11 +273,8 @@ static int __init vio_bus_init(void)
317 * the device tree. Drivers will associate with them later. 273 * the device tree. Drivers will associate with them later.
318 */ 274 */
319 for (of_node = node_vroot->child; of_node != NULL; 275 for (of_node = node_vroot->child; of_node != NULL;
320 of_node = of_node->sibling) { 276 of_node = of_node->sibling)
321 printk(KERN_DEBUG "%s: processing %p\n",
322 __FUNCTION__, of_node);
323 vio_register_device_node(of_node); 277 vio_register_device_node(of_node);
324 }
325 of_node_put(node_vroot); 278 of_node_put(node_vroot);
326 } 279 }
327 280
@@ -391,14 +344,13 @@ static int vio_hotplug(struct device *dev, char **envp, int num_envp,
391 return 0; 344 return 0;
392} 345}
393 346
394struct bus_type vio_bus_type = { 347static struct bus_type vio_bus_type = {
395 .name = "vio", 348 .name = "vio",
396 .dev_attrs = vio_dev_attrs, 349 .dev_attrs = vio_dev_attrs,
397 .uevent = vio_hotplug, 350 .uevent = vio_hotplug,
398 .match = vio_bus_match, 351 .match = vio_bus_match,
399 .probe = vio_bus_probe, 352 .probe = vio_bus_probe,
400 .remove = vio_bus_remove, 353 .remove = vio_bus_remove,
401 .shutdown = vio_bus_shutdown,
402}; 354};
403 355
404/** 356/**