of: Always use 'struct device.of_node' to get device node pointer.
[safe/jmp/linux-2.6] / drivers / of / device.c
index 8fbfeee..24068bb 100644 (file)
@@ -21,9 +21,9 @@
 const struct of_device_id *of_match_device(const struct of_device_id *matches,
                                        const struct of_device *dev)
 {
-       if (!dev->node)
+       if (!dev->dev.of_node)
                return NULL;
-       return of_match_node(matches, dev->node);
+       return of_match_node(matches, dev->dev.of_node);
 }
 EXPORT_SYMBOL(of_match_device);
 
@@ -54,7 +54,16 @@ static ssize_t devspec_show(struct device *dev,
        struct of_device *ofdev;
 
        ofdev = to_of_device(dev);
-       return sprintf(buf, "%s\n", ofdev->node->full_name);
+       return sprintf(buf, "%s\n", ofdev->dev.of_node->full_name);
+}
+
+static ssize_t name_show(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+{
+       struct of_device *ofdev;
+
+       ofdev = to_of_device(dev);
+       return sprintf(buf, "%s\n", ofdev->dev.of_node->name);
 }
 
 static ssize_t modalias_show(struct device *dev,
@@ -71,6 +80,7 @@ static ssize_t modalias_show(struct device *dev,
 
 struct device_attribute of_platform_device_attrs[] = {
        __ATTR_RO(devspec),
+       __ATTR_RO(name),
        __ATTR_RO(modalias),
        __ATTR_NULL
 };
@@ -87,15 +97,24 @@ void of_release_dev(struct device *dev)
        struct of_device *ofdev;
 
        ofdev = to_of_device(dev);
-       of_node_put(ofdev->node);
+       of_node_put(ofdev->dev.of_node);
        kfree(ofdev);
 }
 EXPORT_SYMBOL(of_release_dev);
 
 int of_device_register(struct of_device *ofdev)
 {
-       BUG_ON(ofdev->node == NULL);
-       return device_register(&ofdev->dev);
+       BUG_ON(ofdev->dev.of_node == NULL);
+
+       device_initialize(&ofdev->dev);
+
+       /* device_add will assume that this device is on the same node as
+        * the parent. If there is no parent defined, set the node
+        * explicitly */
+       if (!ofdev->dev.parent)
+               set_dev_node(&ofdev->dev, of_node_to_nid(ofdev->dev.of_node));
+
+       return device_add(&ofdev->dev);
 }
 EXPORT_SYMBOL(of_device_register);
 
@@ -104,3 +123,51 @@ void of_device_unregister(struct of_device *ofdev)
        device_unregister(&ofdev->dev);
 }
 EXPORT_SYMBOL(of_device_unregister);
+
+ssize_t of_device_get_modalias(struct of_device *ofdev,
+                               char *str, ssize_t len)
+{
+       const char *compat;
+       int cplen, i;
+       ssize_t tsize, csize, repend;
+
+       /* Name & Type */
+       csize = snprintf(str, len, "of:N%sT%s", ofdev->dev.of_node->name,
+                        ofdev->dev.of_node->type);
+
+       /* Get compatible property if any */
+       compat = of_get_property(ofdev->dev.of_node, "compatible", &cplen);
+       if (!compat)
+               return csize;
+
+       /* Find true end (we tolerate multiple \0 at the end */
+       for (i = (cplen - 1); i >= 0 && !compat[i]; i--)
+               cplen--;
+       if (!cplen)
+               return csize;
+       cplen++;
+
+       /* Check space (need cplen+1 chars including final \0) */
+       tsize = csize + cplen;
+       repend = tsize;
+
+       if (csize >= len)               /* @ the limit, all is already filled */
+               return tsize;
+
+       if (tsize >= len) {             /* limit compat list */
+               cplen = len - csize - 1;
+               repend = len;
+       }
+
+       /* Copy and do char replacement */
+       memcpy(&str[csize + 1], compat, cplen);
+       for (i = csize; i < repend; i++) {
+               char c = str[i];
+               if (c == '\0')
+                       str[i] = 'C';
+               else if (c == ' ')
+                       str[i] = '_';
+       }
+
+       return tsize;
+}