On Thu, 10 Sep 2020 16:59:57 +0300 Dmitry Baryshkov <dmitry.baryshkov@xxxxxxxxxx> wrote: > There might be cases when the IIO channel is attached to the device > subnode instead of being attached to the main device node. Allow drivers > to query IIO channels by using device tree nodes. > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@xxxxxxxxxx> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@xxxxxxxxxx> > --- > drivers/iio/inkern.c | 34 ++++++++++++++++++++++++++-------- > include/linux/iio/consumer.h | 36 ++++++++++++++++++++++++++++++++++++ > 2 files changed, 62 insertions(+), 8 deletions(-) > > diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c > index ede99e0d5371..8ff0ac472de3 100644 > --- a/drivers/iio/inkern.c > +++ b/drivers/iio/inkern.c > @@ -180,8 +180,8 @@ static struct iio_channel *of_iio_channel_get(struct device_node *np, int index) > return ERR_PTR(err); > } > > -static struct iio_channel *of_iio_channel_get_by_name(struct device_node *np, > - const char *name) > +struct iio_channel *of_iio_channel_get_by_name(struct device_node *np, > + const char *name) > { > struct iio_channel *chan = NULL; > > @@ -219,6 +219,7 @@ static struct iio_channel *of_iio_channel_get_by_name(struct device_node *np, > > return chan; > } > +EXPORT_SYMBOL_GPL(of_iio_channel_get_by_name); > > static struct iio_channel *of_iio_channel_get_all(struct device *dev) > { > @@ -261,12 +262,6 @@ static struct iio_channel *of_iio_channel_get_all(struct device *dev) > > #else /* CONFIG_OF */ > > -static inline struct iio_channel * > -of_iio_channel_get_by_name(struct device_node *np, const char *name) > -{ > - return NULL; > -} > - > static inline struct iio_channel *of_iio_channel_get_all(struct device *dev) > { > return NULL; > @@ -382,6 +377,29 @@ struct iio_channel *devm_iio_channel_get(struct device *dev, > } > EXPORT_SYMBOL_GPL(devm_iio_channel_get); > > +struct iio_channel *devm_of_iio_channel_get_by_name(struct device *dev, > + struct device_node *np, > + const char *channel_name) > +{ > + struct iio_channel **ptr, *channel; > + > + ptr = devres_alloc(devm_iio_channel_free, sizeof(*ptr), GFP_KERNEL); > + if (!ptr) > + return ERR_PTR(-ENOMEM); > + > + channel = of_iio_channel_get_by_name(np, channel_name); > + if (IS_ERR(channel)) { > + devres_free(ptr); > + return channel; > + } > + > + *ptr = channel; > + devres_add(dev, ptr); > + > + return channel; > +} > +EXPORT_SYMBOL_GPL(devm_of_iio_channel_get_by_name); > + > struct iio_channel *iio_channel_get_all(struct device *dev) > { > const char *name; > diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h > index c4118dcb8e05..0a90ba8fa1bb 100644 > --- a/include/linux/iio/consumer.h > +++ b/include/linux/iio/consumer.h > @@ -13,6 +13,7 @@ > struct iio_dev; > struct iio_chan_spec; > struct device; > +struct device_node; > > /** > * struct iio_channel - everything needed for a consumer to use a channel > @@ -97,6 +98,41 @@ void iio_channel_release_all(struct iio_channel *chan); > */ > struct iio_channel *devm_iio_channel_get_all(struct device *dev); > > +/** > + * of_iio_channel_get_by_name() - get description of all that is needed to access channel. > + * @np: Pointer to consumer device tree node > + * @consumer_channel: Unique name to identify the channel on the consumer > + * side. This typically describes the channels use within > + * the consumer. E.g. 'battery_voltage' > + */ > +#ifdef CONFIG_OF > +struct iio_channel *of_iio_channel_get_by_name(struct device_node *np, const char *name); > +#else > +static inline struct iio_channel * > +of_iio_channel_get_by_name(struct device_node *np, const char *name) > +{ > + return NULL; > +} > +#endif > + > +/** > + * devm_of_iio_channel_get_by_name() - Resource managed version of of_iio_channel_get_by_name(). > + * @dev: Pointer to consumer device. > + * @np: Pointer to consumer device tree node > + * @consumer_channel: Unique name to identify the channel on the consumer > + * side. This typically describes the channels use within > + * the consumer. E.g. 'battery_voltage' > + * > + * Returns a pointer to negative errno if it is not able to get the iio channel > + * otherwise returns valid pointer for iio channel. > + * > + * The allocated iio channel is automatically released when the device is > + * unbound. > + */ > +struct iio_channel *devm_of_iio_channel_get_by_name(struct device *dev, > + struct device_node *np, > + const char *consumer_channel); > + > struct iio_cb_buffer; > /** > * iio_channel_get_all_cb() - register callback for triggered capture