drivers/core/of: Add symlink to device-tree from devices with an OF node

So I've been annoyed lately with having a bunch of devices such as i2c
eeproms (for use by VPDs, server world !) and other bits and pieces that
I want to be able to identify from userspace, and possibly provide
additional data about from FW.

Basically, it boils down to correlating the sysfs device with the OF
tree device node, so that user space can use device-tree info such as
additional "location" or "label" (or whatever else we can come up with)
propreties to identify a given device, or get some attributes of use
about it, etc...

Now, so far, we've done that in some subsystem in a fairly ad-hoc basis
using "devspec" properties. For example, PCI creates them if it can
correlate the probed device with a DT node. Some powerpc specific busses
do that too.

However, i2c doesn't and it would be nice to have something more generic
since technically any device can have a corresponding device tree node.

This patch adds an "of_node" symlink to devices that have a non-NULL
dev->of_node pointer, the patch is pretty trivial and seems to work just
fine for me.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Benjamin Herrenschmidt 2015-02-18 11:25:18 +11:00 committed by Greg Kroah-Hartman
parent e8a51e1b51
commit 5590f3196b
2 changed files with 24 additions and 2 deletions

View file

@ -0,0 +1,10 @@
# Note: This documents additional properties of any device beyond what
# is documented in Documentation/sysfs-rules.txt
What: /sys/devices/*/of_path
Date: February 2015
Contact: Device Tree mailing list <devicetree@vger.kernel.org>
Description:
Any device associated with a device-tree node will have
an of_path symlink pointing to the corresponding device
node in /sys/firmware/devicetree/

View file

@ -805,8 +805,16 @@ static void cleanup_device_parent(struct device *dev)
static int device_add_class_symlinks(struct device *dev) static int device_add_class_symlinks(struct device *dev)
{ {
struct device_node *of_node = dev_of_node(dev);
int error; int error;
if (of_node) {
error = sysfs_create_link(&dev->kobj, &of_node->kobj,"of_node");
if (error)
dev_warn(dev, "Error %d creating of_node link\n",error);
/* An error here doesn't warrant bringing down the device */
}
if (!dev->class) if (!dev->class)
return 0; return 0;
@ -814,7 +822,7 @@ static int device_add_class_symlinks(struct device *dev)
&dev->class->p->subsys.kobj, &dev->class->p->subsys.kobj,
"subsystem"); "subsystem");
if (error) if (error)
goto out; goto out_devnode;
if (dev->parent && device_is_not_partition(dev)) { if (dev->parent && device_is_not_partition(dev)) {
error = sysfs_create_link(&dev->kobj, &dev->parent->kobj, error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
@ -842,12 +850,16 @@ static int device_add_class_symlinks(struct device *dev)
out_subsys: out_subsys:
sysfs_remove_link(&dev->kobj, "subsystem"); sysfs_remove_link(&dev->kobj, "subsystem");
out: out_devnode:
sysfs_remove_link(&dev->kobj, "of_node");
return error; return error;
} }
static void device_remove_class_symlinks(struct device *dev) static void device_remove_class_symlinks(struct device *dev)
{ {
if (dev_of_node(dev))
sysfs_remove_link(&dev->kobj, "of_node");
if (!dev->class) if (!dev->class)
return; return;