From 9dabaf5eddbafa21aded7c063cb38d2e8936c237 Mon Sep 17 00:00:00 2001 From: Grygorii Strashko Date: Thu, 18 Jul 2013 11:19:00 +0100 Subject: 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 Signed-off-by: Oleksandr Kravchenko Tested-by: Oleksandr Kravchenko Reviewed-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-core.c | 47 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'drivers/iio/industrialio-core.c') diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index e145931ef1b8..d56d1229e2d6 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -912,6 +912,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 **/ -- cgit v1.2.3-70-g09d2