]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/sparc64/kernel/vio.c
driver core: remove KOBJ_NAME_LEN define
[linux-2.6-omap-h63xx.git] / arch / sparc64 / kernel / vio.c
index 491223a6628f92c41cbb4c2c2de4e9d36685d1b7..ecbb8b618b8c46956d4147577f82dd6f2b9732cb 100644 (file)
 #include <asm/mdesc.h>
 #include <asm/vio.h>
 
-static inline int find_in_proplist(const char *list, const char *match,
-                                  int len)
-{
-       while (len > 0) {
-               int l;
-
-               if (!strcmp(list, match))
-                       return 1;
-               l = strlen(list) + 1;
-               list += l;
-               len -= l;
-       }
-       return 0;
-}
-
 static const struct vio_device_id *vio_match_device(
        const struct vio_device_id *matches,
        const struct vio_dev *dev)
@@ -49,7 +34,7 @@ static const struct vio_device_id *vio_match_device(
 
                if (matches->compat[0]) {
                        match &= len &&
-                               find_in_proplist(compat, matches->compat, len);
+                               of_find_in_proplist(compat, matches->compat, len);
                }
                if (match)
                        return matches;
@@ -146,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));
 }
@@ -205,7 +190,8 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
        struct device_node *dp;
        struct vio_dev *vdev;
        int err, tlen, clen;
-       const u64 *id;
+       const u64 *id, *cfg_handle;
+       u64 a;
 
        type = mdesc_get_property(hp, mp, "device-type", &tlen);
        if (!type) {
@@ -221,32 +207,24 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
                return NULL;
        }
 
-       if (!strcmp(type, "vdc-port")) {
-               u64 a;
+       id = mdesc_get_property(hp, mp, "id", NULL);
 
-               id = NULL;
-               mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_BACK) {
-                       u64 target;
+       cfg_handle = NULL;
+       mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_BACK) {
+               u64 target;
 
-                       target = mdesc_arc_target(hp, a);
-                       id = mdesc_get_property(hp, target,
+               target = mdesc_arc_target(hp, a);
+               cfg_handle = mdesc_get_property(hp, target,
                                                "cfg-handle", NULL);
-                       if (id)
-                               break;
-               }
-               if (!id) {
-                       printk(KERN_ERR "VIO: vdc-port lacks parent "
-                              "cfg-handle.\n");
-                       return NULL;
-               }
-       } else
-               id = mdesc_get_property(hp, mp, "id", NULL);
+               if (cfg_handle)
+                       break;
+       }
 
        bus_id_name = type;
        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;
@@ -285,10 +263,14 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
                snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s",
                         bus_id_name);
                vdev->dev_no = ~(u64)0;
-       } else {
+       } else if (!cfg_handle) {
                snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%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);
+               vdev->dev_no = *cfg_handle;
        }
 
        vdev->dev.parent = parent;
@@ -310,7 +292,7 @@ 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", vdev->dev.bus_id);
 
        err = device_register(&vdev->dev);
        if (err) {
@@ -360,8 +342,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",
 };
@@ -409,7 +416,7 @@ static int __init vio_init(void)
                       "property\n");
                goto out_release;
        }
-       if (!find_in_proplist(compat, channel_devices_compat, len)) {
+       if (!of_find_in_proplist(compat, channel_devices_compat, len)) {
                printk(KERN_ERR "VIO: Channel devices node lacks (%s) "
                       "compat entry.\n", channel_devices_compat);
                goto out_release;