Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iio: core: Support reading extended name as label

The point of this new change is to make the IIO tree actually parsable.

Before, given this attribute as a filename:
in_voltage0_aux_sample_rate

Userspace had no way to know if the attribute name was
"aux_sample_rate" with no extended name, or "sample_rate" with "aux" as
the extended name, or just "rate" with "aux_sample" as the extended
name.

This was somewhat possible to deduce when there was more than one
attribute present for a given channel, e.g:
in_voltage0_aux_sample_rate
in_voltage0_aux_frequency

There, it was possible to deduce that "aux" was the extended name. But
even with more than one attribute, this wasn't very robust, as two
attributes starting with the same prefix (e.g. "sample_rate" and
"sample_size") would result in the first part of the prefix being
interpreted as being part of the extended name.

To address the issue, knowing that channels will never have both a label
and an extended name, set the channel's label to the extended name.
In this case, the label's attribute will also have the extended name in
its filename, but we can live with that - userspace can open
in_voltage0_<prefix>_label and verify that it returns <prefix> to obtain
the extended name.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Link: https://lore.kernel.org/r/20210618123005.49867-3-paul@crapouillou.net
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Paul Cercueil and committed by
Jonathan Cameron
13efdc3d 0e0761f8

+7 -4
+7 -4
drivers/iio/industrialio-core.c
··· 740 740 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 741 741 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); 742 742 743 - if (!indio_dev->info->read_label) 744 - return -EINVAL; 743 + if (indio_dev->info->read_label) 744 + return indio_dev->info->read_label(indio_dev, this_attr->c, buf); 745 745 746 - return indio_dev->info->read_label(indio_dev, this_attr->c, buf); 746 + if (this_attr->c->extend_name) 747 + return sprintf(buf, "%s\n", this_attr->c->extend_name); 748 + 749 + return -EINVAL; 747 750 } 748 751 749 752 static ssize_t iio_read_channel_info(struct device *dev, ··· 1186 1183 struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); 1187 1184 int ret; 1188 1185 1189 - if (!indio_dev->info->read_label) 1186 + if (!indio_dev->info->read_label && !chan->extend_name) 1190 1187 return 0; 1191 1188 1192 1189 ret = __iio_add_chan_devattr("label",