@@ -2131,6 +2131,10 @@ EXPORT_SYMBOL_GPL(iio_device_claim_direct_mode);
*/
void iio_device_release_direct_mode(struct iio_dev *indio_dev)
{
+ /* Auto cleanup can result in this being called with an ERR_PTR */
+ if (IS_ERR(indio_dev))
+ return;
+
mutex_unlock(&to_iio_dev_opaque(indio_dev)->mlock);
}
EXPORT_SYMBOL_GPL(iio_device_release_direct_mode);
@@ -9,6 +9,7 @@
#include <linux/device.h>
#include <linux/cdev.h>
+#include <linux/cleanup.h>
#include <linux/slab.h>
#include <linux/iio/types.h>
/* IIO TODO LIST */
@@ -644,6 +645,27 @@ int __devm_iio_device_register(struct device *dev, struct iio_dev *indio_dev,
int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp);
int iio_device_claim_direct_mode(struct iio_dev *indio_dev);
void iio_device_release_direct_mode(struct iio_dev *indio_dev);
+
+/* This autocleanup logic is normally used via iio_claim_direct_scoped */
+DEFINE_GUARD(iio_claim_direct, struct iio_dev *, iio_device_claim_direct_mode(_T),
+ iio_device_release_direct_mode(_T))
+DEFINE_GUARD_COND(iio_claim_direct, _try, ({
+ struct iio_dev *dev;
+ int d = iio_device_claim_direct_mode(_T);
+
+ if (d < 0)
+ dev = NULL;
+ else
+ dev = _T;
+ dev;
+ }))
+/**
+ * iio_device_claim_direct_scoped() - Scoped call to iio_device_claim_direct.
+ * @fail: What to do on failure to claim device.
+ * @iio_dev: Pointer to the IIO devices structure
+ */
+#define iio_device_claim_direct_scoped(fail, iio_dev) \
+ scoped_cond_guard(iio_claim_direct_try, fail, iio_dev)
int iio_device_claim_buffer_mode(struct iio_dev *indio_dev);
void iio_device_release_buffer_mode(struct iio_dev *indio_dev);