summaryrefslogtreecommitdiff
path: root/drivers/iio
diff options
context:
space:
mode:
authorGrygorii Strashko <grygorii.strashko@ti.com>2013-07-18 11:19:00 +0100
committerLaxman Dewangan <ldewangan@nvidia.com>2014-02-16 08:22:18 -0800
commit4efcbcea64decdc50425d5e938c8c682fbdd4830 (patch)
tree916993110bcc213f929a0bd2c1835a6c7fd5dfe1 /drivers/iio
parentd3beafe6fea4bc441d75afcf6e2b0987ba659112 (diff)
iio: core: implement devm_iio_device_alloc/devm_iio_device_free
Add a resource managed devm_iio_device_alloc()/devm_iio_device_free() to automatically clean up any allocations made by IIO drivers, thus leading to simplified IIO drivers code. In addition, this will allow IIO drivers to use other devm_*() API (like devm_request_irq) and don't care about the race between iio_device_free() and the release of resources by Device core during driver removing. Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com> Signed-off-by: Oleksandr Kravchenko <o.v.kravchenko@globallogic.com> Tested-by: Oleksandr Kravchenko <o.v.kravchenko@globallogic.com> Reviewed-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Jonathan Cameron <jic23@kernel.org> (cherry picked from commit 9dabaf5eddbafa21aded7c063cb38d2e8936c237) Change-Id: Ia761b80971ed58d735e39b93f32db4b510368363 Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Reviewed-on: http://git-master/r/368083
Diffstat (limited to 'drivers/iio')
-rw-r--r--drivers/iio/industrialio-core.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index cf9252c91acf..dc4b3ea1dcd6 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -914,6 +914,53 @@ void iio_device_free(struct iio_dev *dev)
}
EXPORT_SYMBOL(iio_device_free);
+static void devm_iio_device_release(struct device *dev, void *res)
+{
+ iio_device_free(*(struct iio_dev **)res);
+}
+
+static int devm_iio_device_match(struct device *dev, void *res, void *data)
+{
+ struct iio_dev **r = res;
+ if (!r || !*r) {
+ WARN_ON(!r || !*r);
+ return 0;
+ }
+ return *r == data;
+}
+
+struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv)
+{
+ struct iio_dev **ptr, *iio_dev;
+
+ ptr = devres_alloc(devm_iio_device_release, sizeof(*ptr),
+ GFP_KERNEL);
+ if (!ptr)
+ return NULL;
+
+ /* use raw alloc_dr for kmalloc caller tracing */
+ iio_dev = iio_device_alloc(sizeof_priv);
+ if (iio_dev) {
+ *ptr = iio_dev;
+ devres_add(dev, ptr);
+ } else {
+ devres_free(ptr);
+ }
+
+ return iio_dev;
+}
+EXPORT_SYMBOL_GPL(devm_iio_device_alloc);
+
+void devm_iio_device_free(struct device *dev, struct iio_dev *iio_dev)
+{
+ int rc;
+
+ rc = devres_release(dev, devm_iio_device_release,
+ devm_iio_device_match, iio_dev);
+ WARN_ON(rc);
+}
+EXPORT_SYMBOL_GPL(devm_iio_device_free);
+
/**
* iio_chrdev_open() - chrdev file open for buffer access and ioctls
**/