Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Grygorii Strashko and committed by
Jonathan Cameron
9dabaf5e 60b188f0

+72
+47
drivers/iio/industrialio-core.c
··· 912 912 } 913 913 EXPORT_SYMBOL(iio_device_free); 914 914 915 + static void devm_iio_device_release(struct device *dev, void *res) 916 + { 917 + iio_device_free(*(struct iio_dev **)res); 918 + } 919 + 920 + static int devm_iio_device_match(struct device *dev, void *res, void *data) 921 + { 922 + struct iio_dev **r = res; 923 + if (!r || !*r) { 924 + WARN_ON(!r || !*r); 925 + return 0; 926 + } 927 + return *r == data; 928 + } 929 + 930 + struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv) 931 + { 932 + struct iio_dev **ptr, *iio_dev; 933 + 934 + ptr = devres_alloc(devm_iio_device_release, sizeof(*ptr), 935 + GFP_KERNEL); 936 + if (!ptr) 937 + return NULL; 938 + 939 + /* use raw alloc_dr for kmalloc caller tracing */ 940 + iio_dev = iio_device_alloc(sizeof_priv); 941 + if (iio_dev) { 942 + *ptr = iio_dev; 943 + devres_add(dev, ptr); 944 + } else { 945 + devres_free(ptr); 946 + } 947 + 948 + return iio_dev; 949 + } 950 + EXPORT_SYMBOL_GPL(devm_iio_device_alloc); 951 + 952 + void devm_iio_device_free(struct device *dev, struct iio_dev *iio_dev) 953 + { 954 + int rc; 955 + 956 + rc = devres_release(dev, devm_iio_device_release, 957 + devm_iio_device_match, iio_dev); 958 + WARN_ON(rc); 959 + } 960 + EXPORT_SYMBOL_GPL(devm_iio_device_free); 961 + 915 962 /** 916 963 * iio_chrdev_open() - chrdev file open for buffer access and ioctls 917 964 **/
+25
include/linux/iio/iio.h
··· 532 532 void iio_device_free(struct iio_dev *indio_dev); 533 533 534 534 /** 535 + * devm_iio_device_alloc - Resource-managed iio_device_alloc() 536 + * @dev: Device to allocate iio_dev for 537 + * @sizeof_priv: Space to allocate for private structure. 538 + * 539 + * Managed iio_device_alloc. iio_dev allocated with this function is 540 + * automatically freed on driver detach. 541 + * 542 + * If an iio_dev allocated with this function needs to be freed separately, 543 + * devm_iio_device_free() must be used. 544 + * 545 + * RETURNS: 546 + * Pointer to allocated iio_dev on success, NULL on failure. 547 + */ 548 + struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv); 549 + 550 + /** 551 + * devm_iio_device_free - Resource-managed iio_device_free() 552 + * @dev: Device this iio_dev belongs to 553 + * @indio_dev: the iio_dev associated with the device 554 + * 555 + * Free indio_dev allocated with devm_iio_device_alloc(). 556 + */ 557 + void devm_iio_device_free(struct device *dev, struct iio_dev *iio_dev); 558 + 559 + /** 535 560 * iio_buffer_enabled() - helper function to test if the buffer is enabled 536 561 * @indio_dev: IIO device structure for device 537 562 **/