linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/4] powerpc: add all the iSeries virtual devices to the device tree
@ 2006-04-27  7:09 Stephen Rothwell
  2006-04-27  7:18 ` [PATCH 2/4] powerpc: use the device tree for the iSeries vio bus probe Stephen Rothwell
  0 siblings, 1 reply; 4+ messages in thread
From: Stephen Rothwell @ 2006-04-27  7:09 UTC (permalink / raw)
  To: ppc-dev

We do this by putting them in the flattened device tree at setup time.
This required the flattened device tree blob to be made bigger.

Currenly we don't do anything with these.

Also make a function static.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---

 arch/powerpc/platforms/iseries/setup.c |   88 ++++++++++++++++++++++++++++++++
 arch/powerpc/platforms/iseries/vio.c   |    2 -
 2 files changed, 88 insertions(+), 2 deletions(-)

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

ea41f9a9099decfb4f7b9c061e7e38defa6b4744
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index 3c51448..4862b8e 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -28,6 +28,7 @@ #include <linux/kdev_t.h>
 #include <linux/major.h>
 #include <linux/root_dev.h>
 #include <linux/kernel.h>
+#include <linux/if_ether.h>	/* ETH_ALEN */
 
 #include <asm/processor.h>
 #include <asm/machdep.h>
@@ -45,6 +46,7 @@ #include <asm/paca.h>
 #include <asm/cache.h>
 #include <asm/sections.h>
 #include <asm/abs_addr.h>
+#include <asm/iseries/hv_types.h>
 #include <asm/iseries/hv_lp_config.h>
 #include <asm/iseries/hv_call_event.h>
 #include <asm/iseries/hv_call_xm.h>
@@ -710,7 +712,7 @@ define_machine(iseries) {
 };
 
 struct blob {
-	unsigned char data[PAGE_SIZE];
+	unsigned char data[PAGE_SIZE * 2];
 	unsigned long next;
 };
 
@@ -911,6 +913,88 @@ void dt_model(struct iseries_flat_dt *dt
 	dt_prop_str(dt, "compatible", "IBM,iSeries");
 }
 
+void dt_vdevices(struct iseries_flat_dt *dt)
+{
+	u32 reg = 0;
+	HvLpIndexMap vlan_map;
+	int i;
+	char buf[32];
+
+	dt_start_node(dt, "vdevice");
+	dt_prop_u32(dt, "#address-cells", 1);
+	dt_prop_u32(dt, "#size-cells", 0);
+
+	snprintf(buf, sizeof(buf), "viocons@%08x", reg);
+	dt_start_node(dt, buf);
+	dt_prop_str(dt, "device_type", "serial");
+	dt_prop_empty(dt, "compatible");
+	dt_prop_u32(dt, "reg", reg);
+	dt_end_node(dt);
+	reg++;
+
+	snprintf(buf, sizeof(buf), "v-scsi@%08x", reg);
+	dt_start_node(dt, buf);
+	dt_prop_str(dt, "device_type", "vscsi");
+	dt_prop_str(dt, "compatible", "IBM,v-scsi");
+	dt_prop_u32(dt, "reg", reg);
+	dt_end_node(dt);
+	reg++;
+
+	vlan_map = HvLpConfig_getVirtualLanIndexMap();
+	for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++) {
+		unsigned char mac_addr[ETH_ALEN];
+
+		if ((vlan_map & (0x8000 >> i)) == 0)
+			continue;
+		snprintf(buf, 32, "vlan@%08x", reg + i);
+		dt_start_node(dt, buf);
+		dt_prop_str(dt, "device_type", "vlan");
+		dt_prop_empty(dt, "compatible");
+		dt_prop_u32(dt, "reg", reg + i);
+
+		mac_addr[0] = 0x02;
+		mac_addr[1] = 0x01;
+		mac_addr[2] = 0xff;
+		mac_addr[3] = i;
+		mac_addr[4] = 0xff;
+		mac_addr[5] = HvLpConfig_getLpIndex_outline();
+		dt_prop(dt, "local-mac-address", (char *)mac_addr, ETH_ALEN);
+		dt_prop(dt, "mac-address", (char *)mac_addr, ETH_ALEN);
+
+		dt_end_node(dt);
+	}
+	reg += HVMAXARCHITECTEDVIRTUALLANS;
+
+	for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++) {
+		snprintf(buf, 32, "viodasd@%08x", reg + i);
+		dt_start_node(dt, buf);
+		dt_prop_str(dt, "device_type", "viodasd");
+		dt_prop_empty(dt, "compatible");
+		dt_prop_u32(dt, "reg", reg + i);
+		dt_end_node(dt);
+	}
+	reg += HVMAXARCHITECTEDVIRTUALDISKS;
+	for (i = 0; i < HVMAXARCHITECTEDVIRTUALCDROMS; i++) {
+		snprintf(buf, 32, "viocd@%08x", reg + i);
+		dt_start_node(dt, buf);
+		dt_prop_str(dt, "device_type", "viocd");
+		dt_prop_empty(dt, "compatible");
+		dt_prop_u32(dt, "reg", reg + i);
+		dt_end_node(dt);
+	}
+	reg += HVMAXARCHITECTEDVIRTUALCDROMS;
+	for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++) {
+		snprintf(buf, 32, "viotape@%08x", reg + i);
+		dt_start_node(dt, buf);
+		dt_prop_str(dt, "device_type", "viotape");
+		dt_prop_empty(dt, "compatible");
+		dt_prop_u32(dt, "reg", reg + i);
+		dt_end_node(dt);
+	}
+
+	dt_end_node(dt);
+}
+
 void build_flat_dt(struct iseries_flat_dt *dt, unsigned long phys_mem_size)
 {
 	u64 tmp[2];
@@ -941,6 +1025,8 @@ void build_flat_dt(struct iseries_flat_d
 
 	dt_cpus(dt);
 
+	dt_vdevices(dt);
+
 	dt_end_node(dt);
 
 	dt_push_u32(dt, OF_DT_END);
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
index ad36ab0..22045a2 100644
--- a/arch/powerpc/platforms/iseries/vio.c
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -71,7 +71,7 @@ static struct vio_dev *__init vio_regist
 	return viodev;
 }
 
-void __init probe_bus_iseries(void)
+static void __init probe_bus_iseries(void)
 {
 	HvLpIndexMap vlan_map;
 	struct vio_dev *viodev;
-- 
1.3.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/4] powerpc: use the device tree for the iSeries vio bus probe
  2006-04-27  7:09 [PATCH 1/4] powerpc: add all the iSeries virtual devices to the device tree Stephen Rothwell
@ 2006-04-27  7:18 ` Stephen Rothwell
  2006-04-27  7:21   ` [PATCH 3/4] powerpc: use a common vio_match_device routine Stephen Rothwell
  0 siblings, 1 reply; 4+ messages in thread
From: Stephen Rothwell @ 2006-04-27  7:18 UTC (permalink / raw)
  To: linuxppc-dev

As an added bonus, since every vio_dev now has a device_node
associated with it, hotplug now works.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---

 arch/powerpc/kernel/vio.c              |  171 +++++++++++++++++++++++++++-----
 arch/powerpc/platforms/iseries/setup.c |    4 +
 arch/powerpc/platforms/iseries/vio.c   |   70 ++-----------
 arch/powerpc/platforms/pseries/vio.c   |  147 ++--------------------------
 include/asm-powerpc/vio.h              |    9 +-
 5 files changed, 169 insertions(+), 232 deletions(-)

Booted on an iSeries 270 and built for pSeries.

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

457201dcad29a4a3fdb7230a6260dcee2c223ddb
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 971020c..9b46eed 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -22,9 +22,7 @@ #include <asm/iommu.h>
 #include <asm/dma.h>
 #include <asm/vio.h>
 #include <asm/prom.h>
-
-static const struct vio_device_id *vio_match_device(
-		const struct vio_device_id *, const struct vio_dev *);
+#include <asm/firmware.h>
 
 struct vio_dev vio_bus_device  = { /* fake "parent" device */
 	.name = vio_bus_device.dev.bus_id,
@@ -35,6 +33,27 @@ struct vio_dev vio_bus_device  = { /* fa
 
 static struct vio_bus_ops vio_bus_ops;
 
+/**
+ * vio_match_device: - Tell if a VIO device has a matching
+ *			VIO device id structure.
+ * @ids:	array of VIO device id structures to search in
+ * @dev:	the VIO device structure to match against
+ *
+ * Used by a driver to check whether a VIO device present in the
+ * system is in its list of supported devices. Returns the matching
+ * vio_device_id structure or NULL if there is no match.
+ */
+static const struct vio_device_id *vio_match_device(
+		const struct vio_device_id *ids, const struct vio_dev *dev)
+{
+	while (ids->type[0] != '\0') {
+		if (vio_bus_ops.match(ids, dev))
+			return ids;
+		ids++;
+	}
+	return NULL;
+}
+
 /*
  * Convert from struct device to struct vio_dev and pass to driver.
  * dev->driver has already been set by generic code because vio_bus_match
@@ -107,25 +126,76 @@ void vio_unregister_driver(struct vio_dr
 EXPORT_SYMBOL(vio_unregister_driver);
 
 /**
- * vio_match_device: - Tell if a VIO device has a matching
- *			VIO device id structure.
- * @ids:	array of VIO device id structures to search in
- * @dev:	the VIO device structure to match against
+ * vio_register_device_node: - Register a new vio device.
+ * @of_node:	The OF node for this device.
  *
- * Used by a driver to check whether a VIO device present in the
- * system is in its list of supported devices. Returns the matching
- * vio_device_id structure or NULL if there is no match.
+ * Creates and initializes a vio_dev structure from the data in
+ * of_node (dev.platform_data) and adds it to the list of virtual devices.
+ * Returns a pointer to the created vio_dev or NULL if node has
+ * NULL device_type or compatible fields.
  */
-static const struct vio_device_id *vio_match_device(
-		const struct vio_device_id *ids, const struct vio_dev *dev)
+struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
 {
-	while (ids->type[0] != '\0') {
-		if (vio_bus_ops.match(ids, dev))
-			return ids;
-		ids++;
+	struct vio_dev *viodev;
+	unsigned int *unit_address;
+	unsigned int *irq_p;
+
+	/* we need the 'device_type' property, in order to match with drivers */
+	if (of_node->type == NULL) {
+		printk(KERN_WARNING "%s: node %s missing 'device_type'\n",
+				__FUNCTION__,
+				of_node->name ? of_node->name : "<unknown>");
+		return NULL;
 	}
-	return NULL;
+
+	unit_address = (unsigned int *)get_property(of_node, "reg", NULL);
+	if (unit_address == NULL) {
+		printk(KERN_WARNING "%s: node %s missing 'reg'\n",
+				__FUNCTION__,
+				of_node->name ? of_node->name : "<unknown>");
+		return NULL;
+	}
+
+	/* allocate a vio_dev for this node */
+	viodev = kzalloc(sizeof(struct vio_dev), GFP_KERNEL);
+	if (viodev == NULL)
+		return NULL;
+
+	viodev->dev.platform_data = of_node_get(of_node);
+
+	viodev->irq = NO_IRQ;
+	irq_p = (unsigned int *)get_property(of_node, "interrupts", NULL);
+	if (irq_p) {
+		int virq = virt_irq_create_mapping(*irq_p);
+		if (virq == NO_IRQ) {
+			printk(KERN_ERR "Unable to allocate interrupt "
+			       "number for %s\n", of_node->full_name);
+		} else
+			viodev->irq = irq_offset_up(virq);
+	}
+
+	snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address);
+	viodev->name = of_node->name;
+	viodev->type = of_node->type;
+	viodev->unit_address = *unit_address;
+	if (firmware_has_feature(FW_FEATURE_ISERIES)) {
+		unit_address = (unsigned int *)get_property(of_node,
+				"linux,unit_address", NULL);
+		if (unit_address != NULL)
+			viodev->unit_address = *unit_address;
+	}
+	viodev->iommu_table = vio_bus_ops.build_iommu_table(viodev);
+
+	/* register with generic device framework */
+	if (vio_register_device(viodev) == NULL) {
+		/* XXX free TCE table */
+		kfree(viodev);
+		return NULL;
+	}
+
+	return viodev;
 }
+EXPORT_SYMBOL(vio_register_device_node);
 
 /**
  * vio_bus_init: - Initialize the virtual IO bus
@@ -133,6 +203,7 @@ static const struct vio_device_id *vio_m
 int __init vio_bus_init(struct vio_bus_ops *ops)
 {
 	int err;
+	struct device_node *node_vroot;
 
 	vio_bus_ops = *ops;
 
@@ -153,23 +224,54 @@ int __init vio_bus_init(struct vio_bus_o
 		return err;
 	}
 
+	node_vroot = find_devices("vdevice");
+	if (node_vroot) {
+		struct device_node *of_node;
+
+		/*
+		 * Create struct vio_devices for each virtual device in
+		 * the device tree. Drivers will associate with them later.
+		 */
+		for (of_node = node_vroot->child; of_node != NULL;
+				of_node = of_node->sibling) {
+			printk(KERN_DEBUG "%s: processing %p\n",
+					__FUNCTION__, of_node);
+			vio_register_device_node(of_node);
+		}
+	}
+
 	return 0;
 }
 
 /* vio_dev refcount hit 0 */
 static void __devinit vio_dev_release(struct device *dev)
 {
-	if (vio_bus_ops.release_device)
-		vio_bus_ops.release_device(dev);
+	if (dev->platform_data) {
+		/* XXX free TCE table */
+		of_node_put(dev->platform_data);
+	}
 	kfree(to_vio_dev(dev));
 }
 
-static ssize_t viodev_show_name(struct device *dev,
+static ssize_t name_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
 	return sprintf(buf, "%s\n", to_vio_dev(dev)->name);
 }
-DEVICE_ATTR(name, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_name, NULL);
+
+static ssize_t devspec_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct device_node *of_node = dev->platform_data;
+
+	return sprintf(buf, "%s\n", of_node ? of_node->full_name : "none");
+}
+
+static struct device_attribute vio_dev_attrs[] = {
+	__ATTR_RO(name),
+	__ATTR_RO(devspec),
+	__ATTR_NULL
+};
 
 struct vio_dev * __devinit vio_register_device(struct vio_dev *viodev)
 {
@@ -184,16 +286,12 @@ struct vio_dev * __devinit vio_register_
 				__FUNCTION__, viodev->dev.bus_id);
 		return NULL;
 	}
-	device_create_file(&viodev->dev, &dev_attr_name);
 
 	return viodev;
 }
 
 void __devinit vio_unregister_device(struct vio_dev *viodev)
 {
-	if (vio_bus_ops.unregister_device)
-		vio_bus_ops.unregister_device(viodev);
-	device_remove_file(&viodev->dev, &dev_attr_name);
 	device_unregister(&viodev->dev);
 }
 EXPORT_SYMBOL(vio_unregister_device);
@@ -267,22 +365,23 @@ static int vio_hotplug(struct device *de
 			char *buffer, int buffer_size)
 {
 	const struct vio_dev *vio_dev = to_vio_dev(dev);
+	struct device_node *dn = dev->platform_data;
 	char *cp;
 	int length;
 
 	if (!num_envp)
 		return -ENOMEM;
 
-	if (!vio_dev->dev.platform_data)
+	if (!dn)
 		return -ENODEV;
-	cp = (char *)get_property(vio_dev->dev.platform_data, "compatible", &length);
+	cp = (char *)get_property(dn, "compatible", &length);
 	if (!cp)
 		return -ENODEV;
 
 	envp[0] = buffer;
 	length = scnprintf(buffer, buffer_size, "MODALIAS=vio:T%sS%s",
 				vio_dev->type, cp);
-	if (buffer_size - length <= 0)
+	if ((buffer_size - length) <= 0)
 		return -ENOMEM;
 	envp[1] = NULL;
 	return 0;
@@ -290,9 +389,25 @@ static int vio_hotplug(struct device *de
 
 struct bus_type vio_bus_type = {
 	.name = "vio",
+	.dev_attrs = vio_dev_attrs,
 	.uevent = vio_hotplug,
 	.match = vio_bus_match,
 	.probe = vio_bus_probe,
 	.remove = vio_bus_remove,
 	.shutdown = vio_bus_shutdown,
 };
+
+/**
+ * vio_get_attribute: - get attribute for virtual device
+ * @vdev:	The vio device to get property.
+ * @which:	The property/attribute to be extracted.
+ * @length:	Pointer to length of returned data size (unused if NULL).
+ *
+ * Calls prom.c's get_property() to return the value of the
+ * attribute specified by @which
+*/
+const void *vio_get_attribute(struct vio_dev *vdev, char *which, int *length)
+{
+	return get_property(vdev->dev.platform_data, which, length);
+}
+EXPORT_SYMBOL(vio_get_attribute);
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index 4862b8e..901acbc 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -951,6 +951,7 @@ void dt_vdevices(struct iseries_flat_dt 
 		dt_prop_str(dt, "device_type", "vlan");
 		dt_prop_empty(dt, "compatible");
 		dt_prop_u32(dt, "reg", reg + i);
+		dt_prop_u32(dt, "linux,unit_address", i);
 
 		mac_addr[0] = 0x02;
 		mac_addr[1] = 0x01;
@@ -971,6 +972,7 @@ void dt_vdevices(struct iseries_flat_dt 
 		dt_prop_str(dt, "device_type", "viodasd");
 		dt_prop_empty(dt, "compatible");
 		dt_prop_u32(dt, "reg", reg + i);
+		dt_prop_u32(dt, "linux,unit_address", i);
 		dt_end_node(dt);
 	}
 	reg += HVMAXARCHITECTEDVIRTUALDISKS;
@@ -980,6 +982,7 @@ void dt_vdevices(struct iseries_flat_dt 
 		dt_prop_str(dt, "device_type", "viocd");
 		dt_prop_empty(dt, "compatible");
 		dt_prop_u32(dt, "reg", reg + i);
+		dt_prop_u32(dt, "linux,unit_address", i);
 		dt_end_node(dt);
 	}
 	reg += HVMAXARCHITECTEDVIRTUALCDROMS;
@@ -989,6 +992,7 @@ void dt_vdevices(struct iseries_flat_dt 
 		dt_prop_str(dt, "device_type", "viotape");
 		dt_prop_empty(dt, "compatible");
 		dt_prop_u32(dt, "reg", reg + i);
+		dt_prop_u32(dt, "linux,unit_address", i);
 		dt_end_node(dt);
 	}
 
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
index 22045a2..a689da6 100644
--- a/arch/powerpc/platforms/iseries/vio.c
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -43,58 +43,11 @@ static void __init iommu_vio_init(void)
 		printk("Virtual Bus VIO TCE table failed.\n");
 }
 
-/**
- * vio_register_device_iseries: - Register a new iSeries vio device.
- * @voidev:	The device to register.
- */
-static struct vio_dev *__init vio_register_device_iseries(char *type,
-		uint32_t unit_num)
+static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
 {
-	struct vio_dev *viodev;
-
-	/* allocate a vio_dev for this device */
-	viodev = kmalloc(sizeof(struct vio_dev), GFP_KERNEL);
-	if (!viodev)
-		return NULL;
-	memset(viodev, 0, sizeof(struct vio_dev));
-
-	snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%s%d", type, unit_num);
-
-	viodev->name = viodev->dev.bus_id;
-	viodev->type = type;
-	viodev->unit_address = unit_num;
-	viodev->iommu_table = &vio_iommu_table;
-	if (vio_register_device(viodev) == NULL) {
-		kfree(viodev);
-		return NULL;
-	}
-	return viodev;
-}
-
-static void __init probe_bus_iseries(void)
-{
-	HvLpIndexMap vlan_map;
-	struct vio_dev *viodev;
-	int i;
-
-	/* there is only one of each of these */
-	vio_register_device_iseries("viocons", 0);
-	vio_register_device_iseries("vscsi", 0);
-
-	vlan_map = HvLpConfig_getVirtualLanIndexMap();
-	for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++) {
-		if ((vlan_map & (0x8000 >> i)) == 0)
-			continue;
-		viodev = vio_register_device_iseries("vlan", i);
-		/* veth is special and has it own iommu_table */
-		viodev->iommu_table = &veth_iommu_table;
-	}
-	for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++)
-		vio_register_device_iseries("viodasd", i);
-	for (i = 0; i < HVMAXARCHITECTEDVIRTUALCDROMS; i++)
-		vio_register_device_iseries("viocd", i);
-	for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++)
-		vio_register_device_iseries("viotape", i);
+	if (strcmp(dev->type, "vlan") == 0)
+		return &veth_iommu_table;
+	return &vio_iommu_table;
 }
 
 /**
@@ -109,6 +62,7 @@ static int vio_match_device_iseries(cons
 
 static struct vio_bus_ops vio_bus_ops_iseries = {
 	.match = vio_match_device_iseries,
+	.build_iommu_table = vio_build_iommu_table,
 };
 
 /**
@@ -116,16 +70,10 @@ static struct vio_bus_ops vio_bus_ops_is
  */
 static int __init vio_bus_init_iseries(void)
 {
-	int err;
-
-	err = vio_bus_init(&vio_bus_ops_iseries);
-	if (err == 0) {
-		iommu_vio_init();
-		vio_bus_device.iommu_table = &vio_iommu_table;
-		iSeries_vio_dev = &vio_bus_device.dev;
-		probe_bus_iseries();
-	}
-	return err;
+	iommu_vio_init();
+	vio_bus_device.iommu_table = &vio_iommu_table;
+	iSeries_vio_dev = &vio_bus_device.dev;
+	return vio_bus_init(&vio_bus_ops_iseries);
 }
 
 __initcall(vio_bus_init_iseries);
diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c
index 8e53e04..b3925ae 100644
--- a/arch/powerpc/platforms/pseries/vio.c
+++ b/arch/powerpc/platforms/pseries/vio.c
@@ -26,26 +26,6 @@ #include <asm/tce.h>
 
 extern struct subsystem devices_subsys; /* needed for vio_find_name() */
 
-static void probe_bus_pseries(void)
-{
-	struct device_node *node_vroot, *of_node;
-
-	node_vroot = find_devices("vdevice");
-	if ((node_vroot == NULL) || (node_vroot->child == NULL))
-		/* this machine doesn't do virtual IO, and that's ok */
-		return;
-
-	/*
-	 * Create struct vio_devices for each virtual device in the device tree.
-	 * Drivers will associate with them later.
-	 */
-	for (of_node = node_vroot->child; of_node != NULL;
-			of_node = of_node->sibling) {
-		printk(KERN_DEBUG "%s: processing %p\n", __FUNCTION__, of_node);
-		vio_register_device_node(of_node);
-	}
-}
-
 /**
  * vio_match_device_pseries: - Tell if a pSeries VIO device matches a
  *	vio_device_id
@@ -57,47 +37,6 @@ static int vio_match_device_pseries(cons
 			device_is_compatible(dev->dev.platform_data, id->compat);
 }
 
-static void vio_release_device_pseries(struct device *dev)
-{
-	/* XXX free TCE table */
-	of_node_put(dev->platform_data);
-}
-
-static ssize_t viodev_show_devspec(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct device_node *of_node = dev->platform_data;
-
-	return sprintf(buf, "%s\n", of_node->full_name);
-}
-DEVICE_ATTR(devspec, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_devspec, NULL);
-
-static void vio_unregister_device_pseries(struct vio_dev *viodev)
-{
-	device_remove_file(&viodev->dev, &dev_attr_devspec);
-}
-
-static struct vio_bus_ops vio_bus_ops_pseries = {
-	.match = vio_match_device_pseries,
-	.unregister_device = vio_unregister_device_pseries,
-	.release_device = vio_release_device_pseries,
-};
-
-/**
- * vio_bus_init_pseries: - Initialize the pSeries virtual IO bus
- */
-static int __init vio_bus_init_pseries(void)
-{
-	int err;
-
-	err = vio_bus_init(&vio_bus_ops_pseries);
-	if (err == 0)
-		probe_bus_pseries();
-	return err;
-}
-
-__initcall(vio_bus_init_pseries);
-
 /**
  * vio_build_iommu_table: - gets the dma information from OF and
  *	builds the TCE tree.
@@ -136,88 +75,20 @@ static struct iommu_table *vio_build_iom
 	return iommu_init_table(newTceTable);
 }
 
+static struct vio_bus_ops vio_bus_ops_pseries = {
+	.match = vio_match_device_pseries,
+	.build_iommu_table = vio_build_iommu_table,
+};
+
 /**
- * vio_register_device_node: - Register a new vio device.
- * @of_node:	The OF node for this device.
- *
- * Creates and initializes a vio_dev structure from the data in
- * of_node (dev.platform_data) and adds it to the list of virtual devices.
- * Returns a pointer to the created vio_dev or NULL if node has
- * NULL device_type or compatible fields.
+ * vio_bus_init_pseries: - Initialize the pSeries virtual IO bus
  */
-struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
+static int __init vio_bus_init_pseries(void)
 {
-	struct vio_dev *viodev;
-	unsigned int *unit_address;
-	unsigned int *irq_p;
-
-	/* we need the 'device_type' property, in order to match with drivers */
-	if ((NULL == of_node->type)) {
-		printk(KERN_WARNING
-			"%s: node %s missing 'device_type'\n", __FUNCTION__,
-			of_node->name ? of_node->name : "<unknown>");
-		return NULL;
-	}
-
-	unit_address = (unsigned int *)get_property(of_node, "reg", NULL);
-	if (!unit_address) {
-		printk(KERN_WARNING "%s: node %s missing 'reg'\n", __FUNCTION__,
-			of_node->name ? of_node->name : "<unknown>");
-		return NULL;
-	}
-
-	/* allocate a vio_dev for this node */
-	viodev = kmalloc(sizeof(struct vio_dev), GFP_KERNEL);
-	if (!viodev) {
-		return NULL;
-	}
-	memset(viodev, 0, sizeof(struct vio_dev));
-
-	viodev->dev.platform_data = of_node_get(of_node);
-
-	viodev->irq = NO_IRQ;
-	irq_p = (unsigned int *)get_property(of_node, "interrupts", NULL);
-	if (irq_p) {
-		int virq = virt_irq_create_mapping(*irq_p);
-		if (virq == NO_IRQ) {
-			printk(KERN_ERR "Unable to allocate interrupt "
-			       "number for %s\n", of_node->full_name);
-		} else
-			viodev->irq = irq_offset_up(virq);
-	}
-
-	snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address);
-	viodev->name = of_node->name;
-	viodev->type = of_node->type;
-	viodev->unit_address = *unit_address;
-	viodev->iommu_table = vio_build_iommu_table(viodev);
-
-	/* register with generic device framework */
-	if (vio_register_device(viodev) == NULL) {
-		/* XXX free TCE table */
-		kfree(viodev);
-		return NULL;
-	}
-	device_create_file(&viodev->dev, &dev_attr_devspec);
-
-	return viodev;
+	return vio_bus_init(&vio_bus_ops_pseries);
 }
-EXPORT_SYMBOL(vio_register_device_node);
 
-/**
- * vio_get_attribute: - get attribute for virtual device
- * @vdev:	The vio device to get property.
- * @which:	The property/attribute to be extracted.
- * @length:	Pointer to length of returned data size (unused if NULL).
- *
- * Calls prom.c's get_property() to return the value of the
- * attribute specified by the preprocessor constant @which
-*/
-const void * vio_get_attribute(struct vio_dev *vdev, void* which, int* length)
-{
-	return get_property(vdev->dev.platform_data, (char*)which, length);
-}
-EXPORT_SYMBOL(vio_get_attribute);
+__initcall(vio_bus_init_pseries);
 
 /* vio_find_name() - internal because only vio.c knows how we formatted the
  * kobject name
diff --git a/include/asm-powerpc/vio.h b/include/asm-powerpc/vio.h
index 0544ece..0055d8e 100644
--- a/include/asm-powerpc/vio.h
+++ b/include/asm-powerpc/vio.h
@@ -66,8 +66,7 @@ struct vio_driver {
 
 struct vio_bus_ops {
 	int (*match)(const struct vio_device_id *id, const struct vio_dev *dev);
-	void (*unregister_device)(struct vio_dev *);
-	void (*release_device)(struct device *);
+	struct iommu_table *(*build_iommu_table)(struct vio_dev *dev);
 };
 
 extern struct dma_mapping_ops vio_dma_ops;
@@ -82,14 +81,14 @@ extern void __devinit vio_unregister_dev
 
 extern int vio_bus_init(struct vio_bus_ops *);
 
-#ifdef CONFIG_PPC_PSERIES
 struct device_node;
 
 extern struct vio_dev * __devinit vio_register_device_node(
 		struct device_node *node_vdev);
-extern struct vio_dev *vio_find_node(struct device_node *vnode);
-extern const void *vio_get_attribute(struct vio_dev *vdev, void *which,
+extern const void *vio_get_attribute(struct vio_dev *vdev, char *which,
 		int *length);
+#ifdef CONFIG_PPC_PSERIES
+extern struct vio_dev *vio_find_node(struct device_node *vnode);
 extern int vio_enable_interrupts(struct vio_dev *dev);
 extern int vio_disable_interrupts(struct vio_dev *dev);
 #endif
-- 
1.3.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 3/4] powerpc: use a common vio_match_device routine
  2006-04-27  7:18 ` [PATCH 2/4] powerpc: use the device tree for the iSeries vio bus probe Stephen Rothwell
@ 2006-04-27  7:21   ` Stephen Rothwell
  2006-04-27  7:23     ` [PATCH 4/4] powerpc: merge the rest of the vio code Stephen Rothwell
  0 siblings, 1 reply; 4+ messages in thread
From: Stephen Rothwell @ 2006-04-27  7:21 UTC (permalink / raw)
  To: ppc-dev

This requires the compatible properties having vaules that are empty
strings instead of just being empty properties.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---

 arch/powerpc/kernel/vio.c              |    3 ++-
 arch/powerpc/platforms/iseries/setup.c |   10 +++++-----
 arch/powerpc/platforms/iseries/vio.c   |   12 ------------
 arch/powerpc/platforms/pseries/vio.c   |   12 ------------
 include/asm-powerpc/vio.h              |    1 -
 5 files changed, 7 insertions(+), 31 deletions(-)

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

2c0c46b1d70d543203c547034bc1a78ab0fb10a9
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 9b46eed..1952929 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -47,7 +47,8 @@ static const struct vio_device_id *vio_m
 		const struct vio_device_id *ids, const struct vio_dev *dev)
 {
 	while (ids->type[0] != '\0') {
-		if (vio_bus_ops.match(ids, dev))
+		if ((strncmp(dev->type, ids->type, strlen(ids->type)) == 0) &&
+		    device_is_compatible(dev->dev.platform_data, ids->compat))
 			return ids;
 		ids++;
 	}
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index 901acbc..befd36a 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -927,7 +927,7 @@ void dt_vdevices(struct iseries_flat_dt 
 	snprintf(buf, sizeof(buf), "viocons@%08x", reg);
 	dt_start_node(dt, buf);
 	dt_prop_str(dt, "device_type", "serial");
-	dt_prop_empty(dt, "compatible");
+	dt_prop_str(dt, "compatible", "");
 	dt_prop_u32(dt, "reg", reg);
 	dt_end_node(dt);
 	reg++;
@@ -949,7 +949,7 @@ void dt_vdevices(struct iseries_flat_dt 
 		snprintf(buf, 32, "vlan@%08x", reg + i);
 		dt_start_node(dt, buf);
 		dt_prop_str(dt, "device_type", "vlan");
-		dt_prop_empty(dt, "compatible");
+		dt_prop_str(dt, "compatible", "");
 		dt_prop_u32(dt, "reg", reg + i);
 		dt_prop_u32(dt, "linux,unit_address", i);
 
@@ -970,7 +970,7 @@ void dt_vdevices(struct iseries_flat_dt 
 		snprintf(buf, 32, "viodasd@%08x", reg + i);
 		dt_start_node(dt, buf);
 		dt_prop_str(dt, "device_type", "viodasd");
-		dt_prop_empty(dt, "compatible");
+		dt_prop_str(dt, "compatible", "");
 		dt_prop_u32(dt, "reg", reg + i);
 		dt_prop_u32(dt, "linux,unit_address", i);
 		dt_end_node(dt);
@@ -980,7 +980,7 @@ void dt_vdevices(struct iseries_flat_dt 
 		snprintf(buf, 32, "viocd@%08x", reg + i);
 		dt_start_node(dt, buf);
 		dt_prop_str(dt, "device_type", "viocd");
-		dt_prop_empty(dt, "compatible");
+		dt_prop_str(dt, "compatible", "");
 		dt_prop_u32(dt, "reg", reg + i);
 		dt_prop_u32(dt, "linux,unit_address", i);
 		dt_end_node(dt);
@@ -990,7 +990,7 @@ void dt_vdevices(struct iseries_flat_dt 
 		snprintf(buf, 32, "viotape@%08x", reg + i);
 		dt_start_node(dt, buf);
 		dt_prop_str(dt, "device_type", "viotape");
-		dt_prop_empty(dt, "compatible");
+		dt_prop_str(dt, "compatible", "");
 		dt_prop_u32(dt, "reg", reg + i);
 		dt_prop_u32(dt, "linux,unit_address", i);
 		dt_end_node(dt);
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
index a689da6..bdd2b7d 100644
--- a/arch/powerpc/platforms/iseries/vio.c
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -50,18 +50,7 @@ static struct iommu_table *vio_build_iom
 	return &vio_iommu_table;
 }
 
-/**
- * vio_match_device_iseries: - Tell if a iSeries VIO device matches a
- *	vio_device_id
- */
-static int vio_match_device_iseries(const struct vio_device_id *id,
-		const struct vio_dev *dev)
-{
-	return strncmp(dev->type, id->type, strlen(id->type)) == 0;
-}
-
 static struct vio_bus_ops vio_bus_ops_iseries = {
-	.match = vio_match_device_iseries,
 	.build_iommu_table = vio_build_iommu_table,
 };
 
@@ -75,5 +64,4 @@ static int __init vio_bus_init_iseries(v
 	iSeries_vio_dev = &vio_bus_device.dev;
 	return vio_bus_init(&vio_bus_ops_iseries);
 }
-
 __initcall(vio_bus_init_iseries);
diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c
index b3925ae..d289166 100644
--- a/arch/powerpc/platforms/pseries/vio.c
+++ b/arch/powerpc/platforms/pseries/vio.c
@@ -27,17 +27,6 @@ #include <asm/tce.h>
 extern struct subsystem devices_subsys; /* needed for vio_find_name() */
 
 /**
- * vio_match_device_pseries: - Tell if a pSeries VIO device matches a
- *	vio_device_id
- */
-static int vio_match_device_pseries(const struct vio_device_id *id,
-		const struct vio_dev *dev)
-{
-	return (strncmp(dev->type, id->type, strlen(id->type)) == 0) &&
-			device_is_compatible(dev->dev.platform_data, id->compat);
-}
-
-/**
  * vio_build_iommu_table: - gets the dma information from OF and
  *	builds the TCE tree.
  * @dev: the virtual device.
@@ -76,7 +65,6 @@ static struct iommu_table *vio_build_iom
 }
 
 static struct vio_bus_ops vio_bus_ops_pseries = {
-	.match = vio_match_device_pseries,
 	.build_iommu_table = vio_build_iommu_table,
 };
 
diff --git a/include/asm-powerpc/vio.h b/include/asm-powerpc/vio.h
index 0055d8e..9c09a8f 100644
--- a/include/asm-powerpc/vio.h
+++ b/include/asm-powerpc/vio.h
@@ -65,7 +65,6 @@ struct vio_driver {
 };
 
 struct vio_bus_ops {
-	int (*match)(const struct vio_device_id *id, const struct vio_dev *dev);
 	struct iommu_table *(*build_iommu_table)(struct vio_dev *dev);
 };
 
-- 
1.3.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 4/4] powerpc: merge the rest of the vio code
  2006-04-27  7:21   ` [PATCH 3/4] powerpc: use a common vio_match_device routine Stephen Rothwell
@ 2006-04-27  7:23     ` Stephen Rothwell
  0 siblings, 0 replies; 4+ messages in thread
From: Stephen Rothwell @ 2006-04-27  7:23 UTC (permalink / raw)
  To: ppc-dev


Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---

 arch/powerpc/kernel/vio.c               |  198 ++++++++++++++++++++++++++-----
 arch/powerpc/platforms/iseries/Makefile |    1 
 arch/powerpc/platforms/iseries/iommu.c  |    3 
 arch/powerpc/platforms/iseries/iommu.h  |   35 -----
 arch/powerpc/platforms/iseries/pci.c    |    2 
 arch/powerpc/platforms/iseries/vio.c    |   67 ----------
 arch/powerpc/platforms/pseries/Makefile |    1 
 arch/powerpc/platforms/pseries/vio.c    |  133 ---------------------
 include/asm-powerpc/iseries/iommu.h     |   35 +++++
 include/asm-powerpc/vio.h               |    8 -
 10 files changed, 201 insertions(+), 282 deletions(-)
 delete mode 100644 arch/powerpc/platforms/iseries/iommu.h
 delete mode 100644 arch/powerpc/platforms/iseries/vio.c
 delete mode 100644 arch/powerpc/platforms/pseries/vio.c
 create mode 100644 include/asm-powerpc/iseries/iommu.h

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

d79e3d667af2d5babcc931a71aa536ff150ba541
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 1952929..ac5c7bf 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -13,25 +13,102 @@
  *      2 of the License, or (at your option) any later version.
  */
 
+#include <linux/types.h>
+#include <linux/device.h>
 #include <linux/init.h>
 #include <linux/console.h>
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/dma-mapping.h>
+#include <linux/kobject.h>
+
 #include <asm/iommu.h>
 #include <asm/dma.h>
 #include <asm/vio.h>
 #include <asm/prom.h>
 #include <asm/firmware.h>
-
-struct vio_dev vio_bus_device  = { /* fake "parent" device */
+#include <asm/tce.h>
+#include <asm/abs_addr.h>
+#include <asm/page.h>
+#include <asm/hvcall.h>
+#include <asm/iseries/vio.h>
+#include <asm/iseries/hv_types.h>
+#include <asm/iseries/hv_lp_config.h>
+#include <asm/iseries/hv_call_xm.h>
+#include <asm/iseries/iommu.h>
+
+extern struct subsystem devices_subsys; /* needed for vio_find_name() */
+
+static struct vio_dev vio_bus_device  = { /* fake "parent" device */
 	.name = vio_bus_device.dev.bus_id,
 	.type = "",
 	.dev.bus_id = "vio",
 	.dev.bus = &vio_bus_type,
 };
 
-static struct vio_bus_ops vio_bus_ops;
+#ifdef CONFIG_PPC_ISERIES
+struct device *iSeries_vio_dev = &vio_bus_device.dev;
+EXPORT_SYMBOL(iSeries_vio_dev);
+
+static struct iommu_table veth_iommu_table;
+static struct iommu_table vio_iommu_table;
+
+static void __init iommu_vio_init(void)
+{
+	iommu_table_getparms_iSeries(255, 0, 0xff, &veth_iommu_table);
+	veth_iommu_table.it_size /= 2;
+	vio_iommu_table = veth_iommu_table;
+	vio_iommu_table.it_offset += veth_iommu_table.it_size;
+
+	if (!iommu_init_table(&veth_iommu_table))
+		printk("Virtual Bus VETH TCE table failed.\n");
+	if (!iommu_init_table(&vio_iommu_table))
+		printk("Virtual Bus VIO TCE table failed.\n");
+}
+#endif
+
+static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
+{
+#ifdef CONFIG_PPC_ISERIES
+	if (firmware_has_feature(FW_FEATURE_ISERIES)) {
+		if (strcmp(dev->type, "vlan") == 0)
+			return &veth_iommu_table;
+		return &vio_iommu_table;
+	} else
+#endif
+	{
+		unsigned int *dma_window;
+		struct iommu_table *newTceTable;
+		unsigned long offset;
+		int dma_window_property_size;
+
+		dma_window = (unsigned int *)get_property(
+				dev->dev.platform_data, "ibm,my-dma-window",
+				&dma_window_property_size);
+		if (!dma_window)
+			return NULL;
+
+		newTceTable = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
+
+		/*
+		 * There should be some code to extract the phys-encoded
+		 * offset using prom_n_addr_cells(). However, according to
+		 * a comment on earlier versions, it's always zero, so we
+		 * don't bother
+		 */
+		offset = dma_window[1] >>  PAGE_SHIFT;
+
+		/* TCE table size - measured in tce entries */
+		newTceTable->it_size = dma_window[4] >> PAGE_SHIFT;
+		/* offset for VIO should always be 0 */
+		newTceTable->it_offset = offset;
+		newTceTable->it_busno = 0;
+		newTceTable->it_index = (unsigned long)dma_window[0];
+		newTceTable->it_type = TCE_VB;
+
+		return iommu_init_table(newTceTable);
+	}
+}
 
 /**
  * vio_match_device: - Tell if a VIO device has a matching
@@ -126,6 +203,16 @@ void vio_unregister_driver(struct vio_dr
 }
 EXPORT_SYMBOL(vio_unregister_driver);
 
+/* vio_dev refcount hit 0 */
+static void __devinit vio_dev_release(struct device *dev)
+{
+	if (dev->platform_data) {
+		/* XXX free TCE table */
+		of_node_put(dev->platform_data);
+	}
+	kfree(to_vio_dev(dev));
+}
+
 /**
  * vio_register_device_node: - Register a new vio device.
  * @of_node:	The OF node for this device.
@@ -185,10 +272,17 @@ struct vio_dev * __devinit vio_register_
 		if (unit_address != NULL)
 			viodev->unit_address = *unit_address;
 	}
-	viodev->iommu_table = vio_bus_ops.build_iommu_table(viodev);
+	viodev->iommu_table = vio_build_iommu_table(viodev);
+
+	/* init generic 'struct device' fields: */
+	viodev->dev.parent = &vio_bus_device.dev;
+	viodev->dev.bus = &vio_bus_type;
+	viodev->dev.release = vio_dev_release;
 
 	/* register with generic device framework */
-	if (vio_register_device(viodev) == NULL) {
+	if (device_register(&viodev->dev)) {
+		printk(KERN_ERR "%s: failed to register device %s\n",
+				__FUNCTION__, viodev->dev.bus_id);
 		/* XXX free TCE table */
 		kfree(viodev);
 		return NULL;
@@ -201,12 +295,18 @@ EXPORT_SYMBOL(vio_register_device_node);
 /**
  * vio_bus_init: - Initialize the virtual IO bus
  */
-int __init vio_bus_init(struct vio_bus_ops *ops)
+static int __init vio_bus_init(void)
 {
 	int err;
 	struct device_node *node_vroot;
 
-	vio_bus_ops = *ops;
+#ifdef CONFIG_PPC_ISERIES
+	if (firmware_has_feature(FW_FEATURE_ISERIES)) {
+		iommu_vio_init();
+		vio_bus_device.iommu_table = &vio_iommu_table;
+		iSeries_vio_dev = &vio_bus_device.dev;
+	}
+#endif
 
 	err = bus_register(&vio_bus_type);
 	if (err) {
@@ -243,16 +343,7 @@ int __init vio_bus_init(struct vio_bus_o
 
 	return 0;
 }
-
-/* vio_dev refcount hit 0 */
-static void __devinit vio_dev_release(struct device *dev)
-{
-	if (dev->platform_data) {
-		/* XXX free TCE table */
-		of_node_put(dev->platform_data);
-	}
-	kfree(to_vio_dev(dev));
-}
+__initcall(vio_bus_init);
 
 static ssize_t name_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
@@ -274,23 +365,6 @@ static struct device_attribute vio_dev_a
 	__ATTR_NULL
 };
 
-struct vio_dev * __devinit vio_register_device(struct vio_dev *viodev)
-{
-	/* init generic 'struct device' fields: */
-	viodev->dev.parent = &vio_bus_device.dev;
-	viodev->dev.bus = &vio_bus_type;
-	viodev->dev.release = vio_dev_release;
-
-	/* register with generic device framework */
-	if (device_register(&viodev->dev)) {
-		printk(KERN_ERR "%s: failed to register device %s\n",
-				__FUNCTION__, viodev->dev.bus_id);
-		return NULL;
-	}
-
-	return viodev;
-}
-
 void __devinit vio_unregister_device(struct vio_dev *viodev)
 {
 	device_unregister(&viodev->dev);
@@ -412,3 +486,59 @@ const void *vio_get_attribute(struct vio
 	return get_property(vdev->dev.platform_data, which, length);
 }
 EXPORT_SYMBOL(vio_get_attribute);
+
+#ifdef CONFIG_PPC_PSERIES
+/* vio_find_name() - internal because only vio.c knows how we formatted the
+ * kobject name
+ * XXX once vio_bus_type.devices is actually used as a kset in
+ * drivers/base/bus.c, this function should be removed in favor of
+ * "device_find(kobj_name, &vio_bus_type)"
+ */
+static struct vio_dev *vio_find_name(const char *kobj_name)
+{
+	struct kobject *found;
+
+	found = kset_find_obj(&devices_subsys.kset, kobj_name);
+	if (!found)
+		return NULL;
+
+	return to_vio_dev(container_of(found, struct device, kobj));
+}
+
+/**
+ * vio_find_node - find an already-registered vio_dev
+ * @vnode: device_node of the virtual device we're looking for
+ */
+struct vio_dev *vio_find_node(struct device_node *vnode)
+{
+	uint32_t *unit_address;
+	char kobj_name[BUS_ID_SIZE];
+
+	/* construct the kobject name from the device node */
+	unit_address = (uint32_t *)get_property(vnode, "reg", NULL);
+	if (!unit_address)
+		return NULL;
+	snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address);
+
+	return vio_find_name(kobj_name);
+}
+EXPORT_SYMBOL(vio_find_node);
+
+int vio_enable_interrupts(struct vio_dev *dev)
+{
+	int rc = h_vio_signal(dev->unit_address, VIO_IRQ_ENABLE);
+	if (rc != H_SUCCESS)
+		printk(KERN_ERR "vio: Error 0x%x enabling interrupts\n", rc);
+	return rc;
+}
+EXPORT_SYMBOL(vio_enable_interrupts);
+
+int vio_disable_interrupts(struct vio_dev *dev)
+{
+	int rc = h_vio_signal(dev->unit_address, VIO_IRQ_DISABLE);
+	if (rc != H_SUCCESS)
+		printk(KERN_ERR "vio: Error 0x%x disabling interrupts\n", rc);
+	return rc;
+}
+EXPORT_SYMBOL(vio_disable_interrupts);
+#endif /* CONFIG_PPC_PSERIES */
diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile
index ce8c0b9..7e67a20 100644
--- a/arch/powerpc/platforms/iseries/Makefile
+++ b/arch/powerpc/platforms/iseries/Makefile
@@ -3,7 +3,6 @@ EXTRA_CFLAGS	+= -mno-minimal-toc
 obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o \
 	hvcall.o proc.o htab.o iommu.o misc.o irq.o
 obj-$(CONFIG_PCI) += pci.o vpdinfo.o
-obj-$(CONFIG_IBMVIO) += vio.o
 obj-$(CONFIG_SMP) += smp.o
 obj-$(CONFIG_VIOPATH) += viopath.o
 obj-$(CONFIG_MODULES) += ksyms.o
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index bea0b70..a8d9631 100644
--- a/arch/powerpc/platforms/iseries/iommu.c
+++ b/arch/powerpc/platforms/iseries/iommu.c
@@ -33,8 +33,7 @@ #include <asm/machdep.h>
 #include <asm/abs_addr.h>
 #include <asm/pci-bridge.h>
 #include <asm/iseries/hv_call_xm.h>
-
-#include "iommu.h"
+#include <asm/iseries/iommu.h>
 
 extern struct list_head iSeries_Global_Device_List;
 
diff --git a/arch/powerpc/platforms/iseries/iommu.h b/arch/powerpc/platforms/iseries/iommu.h
deleted file mode 100644
index cb5658f..0000000
--- a/arch/powerpc/platforms/iseries/iommu.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef _PLATFORMS_ISERIES_IOMMU_H
-#define _PLATFORMS_ISERIES_IOMMU_H
-
-/*
- * Copyright (C) 2005  Stephen Rothwell, IBM Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the:
- * Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330,
- * Boston, MA  02111-1307  USA
- */
-
-struct device_node;
-struct iommu_table;
-
-/* Creates table for an individual device node */
-extern void iommu_devnode_init_iSeries(struct device_node *dn);
-
-/* Get table parameters from HV */
-extern void iommu_table_getparms_iSeries(unsigned long busno,
-		unsigned char slotno, unsigned char virtbus,
-		struct iommu_table *tbl);
-
-#endif /* _PLATFORMS_ISERIES_IOMMU_H */
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c
index 5a61c6f..428ffb5 100644
--- a/arch/powerpc/platforms/iseries/pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -37,13 +37,13 @@ #include <asm/abs_addr.h>
 
 #include <asm/iseries/hv_call_xm.h>
 #include <asm/iseries/mf.h>
+#include <asm/iseries/iommu.h>
 
 #include <asm/ppc-pci.h>
 
 #include "irq.h"
 #include "pci.h"
 #include "call_pci.h"
-#include "iommu.h"
 
 /*
  * Forward declares of prototypes.
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
deleted file mode 100644
index bdd2b7d..0000000
--- a/arch/powerpc/platforms/iseries/vio.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * IBM PowerPC iSeries Virtual I/O Infrastructure Support.
- *
- *    Copyright (c) 2005 Stephen Rothwell, IBM Corp.
- *
- *      This program is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU General Public License
- *      as published by the Free Software Foundation; either version
- *      2 of the License, or (at your option) any later version.
- */
-#include <linux/types.h>
-#include <linux/device.h>
-#include <linux/init.h>
-
-#include <asm/vio.h>
-#include <asm/iommu.h>
-#include <asm/tce.h>
-#include <asm/abs_addr.h>
-#include <asm/page.h>
-#include <asm/iseries/vio.h>
-#include <asm/iseries/hv_types.h>
-#include <asm/iseries/hv_lp_config.h>
-#include <asm/iseries/hv_call_xm.h>
-
-#include "iommu.h"
-
-struct device *iSeries_vio_dev = &vio_bus_device.dev;
-EXPORT_SYMBOL(iSeries_vio_dev);
-
-static struct iommu_table veth_iommu_table;
-static struct iommu_table vio_iommu_table;
-
-static void __init iommu_vio_init(void)
-{
-	iommu_table_getparms_iSeries(255, 0, 0xff, &veth_iommu_table);
-	veth_iommu_table.it_size /= 2;
-	vio_iommu_table = veth_iommu_table;
-	vio_iommu_table.it_offset += veth_iommu_table.it_size;
-
-	if (!iommu_init_table(&veth_iommu_table))
-		printk("Virtual Bus VETH TCE table failed.\n");
-	if (!iommu_init_table(&vio_iommu_table))
-		printk("Virtual Bus VIO TCE table failed.\n");
-}
-
-static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
-{
-	if (strcmp(dev->type, "vlan") == 0)
-		return &veth_iommu_table;
-	return &vio_iommu_table;
-}
-
-static struct vio_bus_ops vio_bus_ops_iseries = {
-	.build_iommu_table = vio_build_iommu_table,
-};
-
-/**
- * vio_bus_init_iseries: - Initialize the iSeries virtual IO bus
- */
-static int __init vio_bus_init_iseries(void)
-{
-	iommu_vio_init();
-	vio_bus_device.iommu_table = &vio_iommu_table;
-	iSeries_vio_dev = &vio_bus_device.dev;
-	return vio_bus_init(&vio_bus_ops_iseries);
-}
-__initcall(vio_bus_init_iseries);
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index 9308986..b46ce3b 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -2,7 +2,6 @@ obj-y			:= pci.o lpar.o hvCall.o nvram.o
 			   setup.o iommu.o ras.o rtasd.o pci_dlpar.o \
 			   firmware.o
 obj-$(CONFIG_SMP)	+= smp.o
-obj-$(CONFIG_IBMVIO)	+= vio.o
 obj-$(CONFIG_XICS)	+= xics.o
 obj-$(CONFIG_SCANLOG)	+= scanlog.o
 obj-$(CONFIG_EEH)	+= eeh.o eeh_cache.o eeh_driver.o eeh_event.o
diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c
deleted file mode 100644
index d289166..0000000
--- a/arch/powerpc/platforms/pseries/vio.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * IBM PowerPC pSeries Virtual I/O Infrastructure Support.
- *
- *    Copyright (c) 2003-2005 IBM Corp.
- *     Dave Engebretsen engebret@us.ibm.com
- *     Santiago Leon santil@us.ibm.com
- *     Hollis Blanchard <hollisb@us.ibm.com>
- *     Stephen Rothwell
- *
- *      This program is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU General Public License
- *      as published by the Free Software Foundation; either version
- *      2 of the License, or (at your option) any later version.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/kobject.h>
-#include <asm/iommu.h>
-#include <asm/dma.h>
-#include <asm/prom.h>
-#include <asm/vio.h>
-#include <asm/hvcall.h>
-#include <asm/tce.h>
-
-extern struct subsystem devices_subsys; /* needed for vio_find_name() */
-
-/**
- * vio_build_iommu_table: - gets the dma information from OF and
- *	builds the TCE tree.
- * @dev: the virtual device.
- *
- * Returns a pointer to the built tce tree, or NULL if it can't
- * find property.
-*/
-static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
-{
-	unsigned int *dma_window;
-	struct iommu_table *newTceTable;
-	unsigned long offset;
-	int dma_window_property_size;
-
-	dma_window = (unsigned int *) get_property(dev->dev.platform_data, "ibm,my-dma-window", &dma_window_property_size);
-	if(!dma_window) {
-		return NULL;
-	}
-
-	newTceTable = (struct iommu_table *) kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
-
-	/*  There should be some code to extract the phys-encoded offset
-		using prom_n_addr_cells(). However, according to a comment
-		on earlier versions, it's always zero, so we don't bother */
-	offset = dma_window[1] >>  PAGE_SHIFT;
-
-	/* TCE table size - measured in tce entries */
-	newTceTable->it_size		= dma_window[4] >> PAGE_SHIFT;
-	/* offset for VIO should always be 0 */
-	newTceTable->it_offset		= offset;
-	newTceTable->it_busno		= 0;
-	newTceTable->it_index		= (unsigned long)dma_window[0];
-	newTceTable->it_type		= TCE_VB;
-
-	return iommu_init_table(newTceTable);
-}
-
-static struct vio_bus_ops vio_bus_ops_pseries = {
-	.build_iommu_table = vio_build_iommu_table,
-};
-
-/**
- * vio_bus_init_pseries: - Initialize the pSeries virtual IO bus
- */
-static int __init vio_bus_init_pseries(void)
-{
-	return vio_bus_init(&vio_bus_ops_pseries);
-}
-
-__initcall(vio_bus_init_pseries);
-
-/* vio_find_name() - internal because only vio.c knows how we formatted the
- * kobject name
- * XXX once vio_bus_type.devices is actually used as a kset in
- * drivers/base/bus.c, this function should be removed in favor of
- * "device_find(kobj_name, &vio_bus_type)"
- */
-static struct vio_dev *vio_find_name(const char *kobj_name)
-{
-	struct kobject *found;
-
-	found = kset_find_obj(&devices_subsys.kset, kobj_name);
-	if (!found)
-		return NULL;
-
-	return to_vio_dev(container_of(found, struct device, kobj));
-}
-
-/**
- * vio_find_node - find an already-registered vio_dev
- * @vnode: device_node of the virtual device we're looking for
- */
-struct vio_dev *vio_find_node(struct device_node *vnode)
-{
-	uint32_t *unit_address;
-	char kobj_name[BUS_ID_SIZE];
-
-	/* construct the kobject name from the device node */
-	unit_address = (uint32_t *)get_property(vnode, "reg", NULL);
-	if (!unit_address)
-		return NULL;
-	snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address);
-
-	return vio_find_name(kobj_name);
-}
-EXPORT_SYMBOL(vio_find_node);
-
-int vio_enable_interrupts(struct vio_dev *dev)
-{
-	int rc = h_vio_signal(dev->unit_address, VIO_IRQ_ENABLE);
-	if (rc != H_SUCCESS)
-		printk(KERN_ERR "vio: Error 0x%x enabling interrupts\n", rc);
-	return rc;
-}
-EXPORT_SYMBOL(vio_enable_interrupts);
-
-int vio_disable_interrupts(struct vio_dev *dev)
-{
-	int rc = h_vio_signal(dev->unit_address, VIO_IRQ_DISABLE);
-	if (rc != H_SUCCESS)
-		printk(KERN_ERR "vio: Error 0x%x disabling interrupts\n", rc);
-	return rc;
-}
-EXPORT_SYMBOL(vio_disable_interrupts);
diff --git a/include/asm-powerpc/iseries/iommu.h b/include/asm-powerpc/iseries/iommu.h
new file mode 100644
index 0000000..0edbfe1
--- /dev/null
+++ b/include/asm-powerpc/iseries/iommu.h
@@ -0,0 +1,35 @@
+#ifndef _ASM_POWERPC_ISERIES_IOMMU_H
+#define _ASM_POWERPC_ISERIES_IOMMU_H
+
+/*
+ * Copyright (C) 2005  Stephen Rothwell, IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the:
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330,
+ * Boston, MA  02111-1307  USA
+ */
+
+struct device_node;
+struct iommu_table;
+
+/* Creates table for an individual device node */
+extern void iommu_devnode_init_iSeries(struct device_node *dn);
+
+/* Get table parameters from HV */
+extern void iommu_table_getparms_iSeries(unsigned long busno,
+		unsigned char slotno, unsigned char virtbus,
+		struct iommu_table *tbl);
+
+#endif /* _ASM_POWERPC_ISERIES_IOMMU_H */
diff --git a/include/asm-powerpc/vio.h b/include/asm-powerpc/vio.h
index 9c09a8f..10da7f3 100644
--- a/include/asm-powerpc/vio.h
+++ b/include/asm-powerpc/vio.h
@@ -64,22 +64,14 @@ struct vio_driver {
 	struct device_driver driver;
 };
 
-struct vio_bus_ops {
-	struct iommu_table *(*build_iommu_table)(struct vio_dev *dev);
-};
-
 extern struct dma_mapping_ops vio_dma_ops;
 extern struct bus_type vio_bus_type;
-extern struct vio_dev vio_bus_device;
 
 extern int vio_register_driver(struct vio_driver *drv);
 extern void vio_unregister_driver(struct vio_driver *drv);
 
-extern struct vio_dev * __devinit vio_register_device(struct vio_dev *viodev);
 extern void __devinit vio_unregister_device(struct vio_dev *dev);
 
-extern int vio_bus_init(struct vio_bus_ops *);
-
 struct device_node;
 
 extern struct vio_dev * __devinit vio_register_device_node(
-- 
1.3.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2006-04-27  7:24 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-04-27  7:09 [PATCH 1/4] powerpc: add all the iSeries virtual devices to the device tree Stephen Rothwell
2006-04-27  7:18 ` [PATCH 2/4] powerpc: use the device tree for the iSeries vio bus probe Stephen Rothwell
2006-04-27  7:21   ` [PATCH 3/4] powerpc: use a common vio_match_device routine Stephen Rothwell
2006-04-27  7:23     ` [PATCH 4/4] powerpc: merge the rest of the vio code Stephen Rothwell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).