Re: [PATCH 2/2 v3] drivers/core/of: Add symlink to device-tree from devices with an OF node

Rob Herring
2015-02-18T01:07:38Z

On Tue, Feb 17, 2015 at 6:25 PM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> 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>

> ---
>
> This addresses Greg's comments. Note that I'm not 100% certain about
> using device_add_class_symlinks(), I had to put the code before the
> test for dev->class, maybe we should rename that function to device_add_symlinks()
> if it grows beyond the class bits ?
>
> Also there was nothing that I could find in Documentation/ABI that
> documented "core" device properties, it's all in
> Documentation/sysfs-rules.txt, but as suggested by Greg (on IRC) I
> went for ABI anyway, so I've added a file for "generic" properties
> and added that one in. I'm happy to change it if you think that's not
> right, just let me know where you want things.
>
> I'm not resending patch 1/2, it should still be fine. Let me know if
> you want a new copy.
>
> Documentation/ABI/stable/sysfs-devices | 10 ++++++++++
> drivers/base/core.c | 16 ++++++++++++++--
> 2 files changed, 24 insertions(+), 2 deletions(-)
> create mode 100644 Documentation/ABI/stable/sysfs-devices
>
> diff --git a/Documentation/ABI/stable/sysfs-devices b/Documentation/ABI/stable/sysfs-devices
> new file mode 100644
> index 0000000..43f78b88d
> --- /dev/null
> +++ b/Documentation/ABI/stable/sysfs-devices
> @@ -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/
> diff --git a/drivers/base/core.c b/drivers/base/core.c
> index 97e2baf..2549805 100644
> --- a/drivers/base/core.c
> +++ b/drivers/base/core.c
> @@ -805,8 +805,16 @@ static void cleanup_device_parent(struct device *dev)
>
> static int device_add_class_symlinks(struct device *dev)
> {
> + struct device_node *of_node = dev_of_node(dev);
> 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)
> return 0;
>
> @@ -814,7 +822,7 @@ static int device_add_class_symlinks(struct device *dev)
> &dev->class->p->subsys.kobj,
> "subsystem");
> if (error)
> - goto out;
> + goto out_devnode;
>
> if (dev->parent && device_is_not_partition(dev)) {
> error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
> @@ -842,12 +850,16 @@ out_device:
>
> out_subsys:
> sysfs_remove_link(&dev->kobj, "subsystem");
> -out:
> +out_devnode:
> + sysfs_remove_link(&dev->kobj, "of_node");
> return error;
> }
>
> static void device_remove_class_symlinks(struct device *dev)
> {
> + if (dev_of_node(dev))
> + sysfs_remove_link(&dev->kobj, "of_node");
> +
> if (!dev->class)
> return;
>
>
>