Merge commit 'upstream/master'
[pandora-kernel.git] / arch / sparc64 / kernel / vio.c
index 1550ac5..a490077 100644 (file)
@@ -131,7 +131,7 @@ void vio_unregister_driver(struct vio_driver *viodrv)
 }
 EXPORT_SYMBOL(vio_unregister_driver);
 
-static void __devinit vio_dev_release(struct device *dev)
+static void vio_dev_release(struct device *dev)
 {
        kfree(to_vio_dev(dev));
 }
@@ -224,7 +224,7 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
        if (!strcmp(type, "domain-services-port"))
                bus_id_name = "ds";
 
-       if (strlen(bus_id_name) >= KOBJ_NAME_LEN - 4) {
+       if (strlen(bus_id_name) >= BUS_ID_SIZE - 4) {
                printk(KERN_ERR "VIO: bus_id_name [%s] is too long.\n",
                       bus_id_name);
                return NULL;
@@ -260,16 +260,14 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
        vio_fill_channel_info(hp, mp, vdev);
 
        if (!id) {
-               snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s",
-                        bus_id_name);
+               dev_set_name(&vdev->dev, "%s", bus_id_name);
                vdev->dev_no = ~(u64)0;
        } else if (!cfg_handle) {
-               snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s-%lu",
-                        bus_id_name, *id);
+               dev_set_name(&vdev->dev, "%s-%lu", bus_id_name, *id);
                vdev->dev_no = *id;
        } else {
-               snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s-%lu-%lu",
-                        bus_id_name, *cfg_handle, *id);
+               dev_set_name(&vdev->dev, "%s-%lu-%lu", bus_id_name,
+                            *cfg_handle, *id);
                vdev->dev_no = *cfg_handle;
        }
 
@@ -292,12 +290,12 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
        }
        vdev->dp = dp;
 
-       printk(KERN_ERR "VIO: Adding device %s\n", vdev->dev.bus_id);
+       printk(KERN_INFO "VIO: Adding device %s\n", dev_name(&vdev->dev));
 
        err = device_register(&vdev->dev);
        if (err) {
                printk(KERN_ERR "VIO: Could not register device %s, err=%d\n",
-                      vdev->dev.bus_id, err);
+                      dev_name(&vdev->dev), err);
                kfree(vdev);
                return NULL;
        }
@@ -330,7 +328,7 @@ static void vio_remove(struct mdesc_handle *hp, u64 node)
        dev = device_find_child(&root_vdev->dev, (void *) node,
                                vio_md_node_match);
        if (dev) {
-               printk(KERN_INFO "VIO: Removing device %s\n", dev->bus_id);
+               printk(KERN_INFO "VIO: Removing device %s\n", dev_name(dev));
 
                device_unregister(dev);
        }
@@ -342,8 +340,33 @@ static struct mdesc_notifier_client vio_device_notifier = {
        .node_name      = "virtual-device-port",
 };
 
+/* We are only interested in domain service ports under the
+ * "domain-services" node.  On control nodes there is another port
+ * under "openboot" that we should not mess with as aparently that is
+ * reserved exclusively for OBP use.
+ */
+static void vio_add_ds(struct mdesc_handle *hp, u64 node)
+{
+       int found;
+       u64 a;
+
+       found = 0;
+       mdesc_for_each_arc(a, hp, node, MDESC_ARC_TYPE_BACK) {
+               u64 target = mdesc_arc_target(hp, a);
+               const char *name = mdesc_node_name(hp, target);
+
+               if (!strcmp(name, "domain-services")) {
+                       found = 1;
+                       break;
+               }
+       }
+
+       if (found)
+               (void) vio_create_one(hp, node, &root_vdev->dev);
+}
+
 static struct mdesc_notifier_client vio_ds_notifier = {
-       .add            = vio_add,
+       .add            = vio_add_ds,
        .remove         = vio_remove,
        .node_name      = "domain-services-port",
 };