aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2005-09-27 13:03:00 -0400
committerStephen Rothwell <sfr@canb.auug.org.au>2005-09-27 13:03:00 -0400
commited7f2c05de956da72baf066701ac642f7215dbf5 (patch)
treee808dab2caed385657af31cbb0cf71e0376e556e /arch/powerpc/platforms
parentda3420fcd62a8967c14a586355e322253a1504a8 (diff)
powerpc: Move iSeries_vio.c to powerpc/platforms/iseries
And rename it to vio.c. Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r--arch/powerpc/platforms/iseries/Makefile1
-rw-r--r--arch/powerpc/platforms/iseries/vio.c156
2 files changed, 157 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile
index d10305d7ad2..3a1ed16963a 100644
--- a/arch/powerpc/platforms/iseries/Makefile
+++ b/arch/powerpc/platforms/iseries/Makefile
@@ -1,3 +1,4 @@
1obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o \ 1obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o \
2 hvcall.o proc.o htab.o iommu.o 2 hvcall.o proc.o htab.o iommu.o
3obj-$(CONFIG_PCI) += pci.o irq.o vpdinfo.o 3obj-$(CONFIG_PCI) += pci.o irq.o vpdinfo.o
4obj-$(CONFIG_IBMVIO) += vio.o
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
new file mode 100644
index 00000000000..c0f7d2e9153
--- /dev/null
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -0,0 +1,156 @@
1/*
2 * IBM PowerPC iSeries Virtual I/O Infrastructure Support.
3 *
4 * Copyright (c) 2005 Stephen Rothwell, IBM Corp.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11#include <linux/types.h>
12#include <linux/device.h>
13#include <linux/init.h>
14
15#include <asm/vio.h>
16#include <asm/iommu.h>
17#include <asm/tce.h>
18#include <asm/abs_addr.h>
19#include <asm/page.h>
20#include <asm/iSeries/vio.h>
21#include <asm/iSeries/HvTypes.h>
22#include <asm/iSeries/HvLpConfig.h>
23#include <asm/iSeries/HvCallXm.h>
24
25struct device *iSeries_vio_dev = &vio_bus_device.dev;
26EXPORT_SYMBOL(iSeries_vio_dev);
27
28static struct iommu_table veth_iommu_table;
29static struct iommu_table vio_iommu_table;
30
31static void __init iommu_vio_init(void)
32{
33 struct iommu_table *t;
34 struct iommu_table_cb cb;
35 unsigned long cbp;
36 unsigned long itc_entries;
37
38 cb.itc_busno = 255; /* Bus 255 is the virtual bus */
39 cb.itc_virtbus = 0xff; /* Ask for virtual bus */
40
41 cbp = virt_to_abs(&cb);
42 HvCallXm_getTceTableParms(cbp);
43
44 itc_entries = cb.itc_size * PAGE_SIZE / sizeof(union tce_entry);
45 veth_iommu_table.it_size = itc_entries / 2;
46 veth_iommu_table.it_busno = cb.itc_busno;
47 veth_iommu_table.it_offset = cb.itc_offset;
48 veth_iommu_table.it_index = cb.itc_index;
49 veth_iommu_table.it_type = TCE_VB;
50 veth_iommu_table.it_blocksize = 1;
51
52 t = iommu_init_table(&veth_iommu_table);
53
54 if (!t)
55 printk("Virtual Bus VETH TCE table failed.\n");
56
57 vio_iommu_table.it_size = itc_entries - veth_iommu_table.it_size;
58 vio_iommu_table.it_busno = cb.itc_busno;
59 vio_iommu_table.it_offset = cb.itc_offset +
60 veth_iommu_table.it_size;
61 vio_iommu_table.it_index = cb.itc_index;
62 vio_iommu_table.it_type = TCE_VB;
63 vio_iommu_table.it_blocksize = 1;
64
65 t = iommu_init_table(&vio_iommu_table);
66
67 if (!t)
68 printk("Virtual Bus VIO TCE table failed.\n");
69}
70
71/**
72 * vio_register_device_iseries: - Register a new iSeries vio device.
73 * @voidev: The device to register.
74 */
75static struct vio_dev *__init vio_register_device_iseries(char *type,
76 uint32_t unit_num)
77{
78 struct vio_dev *viodev;
79
80 /* allocate a vio_dev for this device */
81 viodev = kmalloc(sizeof(struct vio_dev), GFP_KERNEL);
82 if (!viodev)
83 return NULL;
84 memset(viodev, 0, sizeof(struct vio_dev));
85
86 snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%s%d", type, unit_num);
87
88 viodev->name = viodev->dev.bus_id;
89 viodev->type = type;
90 viodev->unit_address = unit_num;
91 viodev->iommu_table = &vio_iommu_table;
92 if (vio_register_device(viodev) == NULL) {
93 kfree(viodev);
94 return NULL;
95 }
96 return viodev;
97}
98
99void __init probe_bus_iseries(void)
100{
101 HvLpIndexMap vlan_map;
102 struct vio_dev *viodev;
103 int i;
104
105 /* there is only one of each of these */
106 vio_register_device_iseries("viocons", 0);
107 vio_register_device_iseries("vscsi", 0);
108
109 vlan_map = HvLpConfig_getVirtualLanIndexMap();
110 for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++) {
111 if ((vlan_map & (0x8000 >> i)) == 0)
112 continue;
113 viodev = vio_register_device_iseries("vlan", i);
114 /* veth is special and has it own iommu_table */
115 viodev->iommu_table = &veth_iommu_table;
116 }
117 for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++)
118 vio_register_device_iseries("viodasd", i);
119 for (i = 0; i < HVMAXARCHITECTEDVIRTUALCDROMS; i++)
120 vio_register_device_iseries("viocd", i);
121 for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++)
122 vio_register_device_iseries("viotape", i);
123}
124
125/**
126 * vio_match_device_iseries: - Tell if a iSeries VIO device matches a
127 * vio_device_id
128 */
129static int vio_match_device_iseries(const struct vio_device_id *id,
130 const struct vio_dev *dev)
131{
132 return strncmp(dev->type, id->type, strlen(id->type)) == 0;
133}
134
135static struct vio_bus_ops vio_bus_ops_iseries = {
136 .match = vio_match_device_iseries,
137};
138
139/**
140 * vio_bus_init_iseries: - Initialize the iSeries virtual IO bus
141 */
142static int __init vio_bus_init_iseries(void)
143{
144 int err;
145
146 err = vio_bus_init(&vio_bus_ops_iseries);
147 if (err == 0) {
148 iommu_vio_init();
149 vio_bus_device.iommu_table = &vio_iommu_table;
150 iSeries_vio_dev = &vio_bus_device.dev;
151 probe_bus_iseries();
152 }
153 return err;
154}
155
156__initcall(vio_bus_init_iseries);