summaryrefslogtreecommitdiffstats
path: root/drivers/iio/inkern.c
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2016-04-06 16:01:07 +0530
committerJonathan Cameron <jic23@kernel.org>2016-04-19 19:58:15 +0100
commitefc2c0133f198bc65593a67015af358919b0c48f (patch)
treea5559eed375f002c6ed912abd05c79e73f4bb7c4 /drivers/iio/inkern.c
parent8bf872d8d261feefcdf67027522e3f717cad2bfe (diff)
downloadlinux-efc2c0133f198bc65593a67015af358919b0c48f.tar.bz2
iio: core: Add devm_ APIs for iio_channel_{get,release}_all
Some of kernel driver uses the IIO framework to get the sensor value via ADC or IIO HW driver. The client driver get iio channel by iio_channel_get_all() and release it by calling iio_channel_release_all(). Add resource managed version (devm_*) of these APIs so that if client calls the devm_iio_channel_get_all() then it need not to release it explicitly, it can be done by managed device framework when driver get un-binded. This reduces the code in error path and also need of .remove callback in some cases. Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'drivers/iio/inkern.c')
-rw-r--r--drivers/iio/inkern.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
index 9fd8934c1887..c4757e6367e7 100644
--- a/drivers/iio/inkern.c
+++ b/drivers/iio/inkern.c
@@ -489,6 +489,42 @@ void iio_channel_release_all(struct iio_channel *channels)
}
EXPORT_SYMBOL_GPL(iio_channel_release_all);
+static void devm_iio_channel_free_all(struct device *dev, void *res)
+{
+ struct iio_channel *channels = *(struct iio_channel **)res;
+
+ iio_channel_release_all(channels);
+}
+
+struct iio_channel *devm_iio_channel_get_all(struct device *dev)
+{
+ struct iio_channel **ptr, *channels;
+
+ ptr = devres_alloc(devm_iio_channel_free_all, sizeof(*ptr), GFP_KERNEL);
+ if (!ptr)
+ return ERR_PTR(-ENOMEM);
+
+ channels = iio_channel_get_all(dev);
+ if (IS_ERR(channels)) {
+ devres_free(ptr);
+ return channels;
+ }
+
+ *ptr = channels;
+ devres_add(dev, ptr);
+
+ return channels;
+}
+EXPORT_SYMBOL_GPL(devm_iio_channel_get_all);
+
+void devm_iio_channel_release_all(struct device *dev,
+ struct iio_channel *channels)
+{
+ WARN_ON(devres_release(dev, devm_iio_channel_free_all,
+ devm_iio_channel_match, channels));
+}
+EXPORT_SYMBOL_GPL(devm_iio_channel_release_all);
+
static int iio_channel_read(struct iio_channel *chan, int *val, int *val2,
enum iio_chan_info_enum info)
{