diff options
author | Grygorii Strashko <grygorii.strashko@ti.com> | 2013-07-18 11:19:00 +0100 |
---|---|---|
committer | Laxman Dewangan <ldewangan@nvidia.com> | 2014-02-16 08:22:18 -0800 |
commit | 4efcbcea64decdc50425d5e938c8c682fbdd4830 (patch) | |
tree | 916993110bcc213f929a0bd2c1835a6c7fd5dfe1 /drivers/iio | |
parent | d3beafe6fea4bc441d75afcf6e2b0987ba659112 (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.c | 47 |
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 **/ |