From: Syunya Ohshio <syunya.ohshio@xxxxxxxxxxxxxxxxx> When using dtb overlays it can be difficult to predict which iio device will get assigned what index, and there is no easy way to create symlinks for /sys nodes through udev so to simplify userspace code make it possible to request fixed indices for iio devices in device tree. For platforms without device trees of_alias_get_id will just fail and ida_alloc_range will behave as ida_alloc currently does. For platforms with device trees, they can not set an alias, for example this would try to get 10 from the ida for the device corresponding to adc2: aliases { iio10 = &adc2 }; To: Jonathan Cameron <jic23@xxxxxxxxxx> Cc: Guido Günther <agx@xxxxxxxxxxx> Cc: Lars-Peter Clausen <lars@xxxxxxxxxx> Cc: Rob Herring <robh+dt@xxxxxxxxxx> Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt@xxxxxxxxxx> Cc: Conor Dooley <conor+dt@xxxxxxxxxx> Cc: linux-iio@xxxxxxxxxxxxxxx Cc: devicetree@xxxxxxxxxxxxxxx Cc: linux-kernel@xxxxxxxxxxxxxxx Signed-off-by: Syunya Ohshio <syunya.ohshio@xxxxxxxxxxxxxxxxx> Signed-off-by: Dominique Martinet <dominique.martinet@xxxxxxxxxxxxxxxxx> --- Hello! We are facing an issue on one of our device where iio devices aren't numbered as we'd like in some situations, and I feel like we could do better than the only alternative I found of making symlinks directly to /sys in /dev as e.g. https://git.toradex.com/cgit/meta-toradex-bsp-common.git/tree/recipes-core/udev/files/verdin-imx8mm/toradex-adc.sh?h=kirkstone-6.x.y Ultimately we'd just like to able to designate a stable path for our users to use in their application and tell them it won't change even if we fiddle with the overlays a bit, which is a problem we had as current init is done in whatever order device tree nodes are processed, and that in turn depends on how the overlays are applied. If you can think of a better way of doing it then we'll be happy to consider something else. Otherwise aliases seem like it could do a good job, and isn't too surprising for users - the main downside I can see would be that it doesn't help platforms without device trees but I honestly don't see what would work well in a more generic way -- looking at /sys/bus/iio/devices/iio:deviceX/name to decide what we're looking at is a bit of a hassle. Thanks! .../devicetree/bindings/iio/common.yaml | 9 +++++++-- drivers/iio/industrialio-core.c | 17 ++++++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/common.yaml b/Documentation/devicetree/bindings/iio/common.yaml index b3a10af86d76..23d4c3012aeb 100644 --- a/Documentation/devicetree/bindings/iio/common.yaml +++ b/Documentation/devicetree/bindings/iio/common.yaml @@ -12,13 +12,18 @@ maintainers: description: | This document defines device tree properties common to several iio - sensors. It doesn't constitute a device tree binding specification by itself but - is meant to be referenced by device tree bindings. + sensors. It doesn't constitute a device tree binding specification by itself + but is meant to be referenced by device tree bindings. When referenced from sensor tree bindings the properties defined in this document are defined as follows. The sensor tree bindings are responsible for defining whether each property is required or optional. + Note: it is also possible to request an index for the iio device through the + "aliases" device tree node. It is however only used as a hint so care should + be taken to either set all devices, or set indices in a range that will not + be used by devices without aliases. + properties: proximity-near-level: $ref: /schemas/types.yaml#/definitions/uint32 diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 173dc00762a1..0f088be3a48c 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -20,6 +20,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/mutex.h> +#include <linux/of.h> #include <linux/poll.h> #include <linux/property.h> #include <linux/sched.h> @@ -1644,6 +1645,7 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv) struct iio_dev_opaque *iio_dev_opaque; struct iio_dev *indio_dev; size_t alloc_size; + int iio_dev_id; alloc_size = sizeof(struct iio_dev_opaque); if (sizeof_priv) { @@ -1667,7 +1669,10 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv) mutex_init(&iio_dev_opaque->info_exist_lock); INIT_LIST_HEAD(&iio_dev_opaque->channel_attr_list); - iio_dev_opaque->id = ida_alloc(&iio_ida, GFP_KERNEL); + iio_dev_id = of_alias_get_id(parent->of_node, "iio"); + iio_dev_opaque->id = ida_alloc_range(&iio_ida, + iio_dev_id < 0 ? 0 : iio_dev_id, + ~0, GFP_KERNEL); if (iio_dev_opaque->id < 0) { /* cannot use a dev_err as the name isn't available */ pr_err("failed to get device id\n"); @@ -1681,6 +1686,16 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv) return NULL; } + /* log about iio_dev_id after dev_set_name() for dev_* helpers */ + if (iio_dev_id < 0) { + dev_dbg(&indio_dev->dev, + "No aliases in fw node for device: %d\n", iio_dev_id); + } else if (iio_dev_opaque->id != iio_dev_id) { + dev_warn(&indio_dev->dev, + "Device requested %d in fw node but could not get it\n", + iio_dev_id); + } + INIT_LIST_HEAD(&iio_dev_opaque->buffer_list); INIT_LIST_HEAD(&iio_dev_opaque->ioctl_handlers); -- 2.39.2