From 2daee817df13fb539be01a6a8094d52667d402f6 Mon Sep 17 00:00:00 2001 From: Kurt Borja Date: Tue, 20 Jan 2026 01:20:43 -0500 Subject: [PATCH] iio: core: Match iio_device_claim_*() semantics and implementation MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Implement iio_device_claim_buffer_mode() fully inline with the use of __iio_dev_mode_lock(), which takes care of sparse annotations. To completely match iio_device_claim_direct() semantics, we need to also change iio_device_claim_buffer_mode() return semantics to usual true/false conditional lock semantics. Additionally, to avoid silently breaking out-of-tree drivers, rename iio_device_claim_buffer_mode() to iio_device_claim_try_buffer_mode(). Reviewed-by: David Lechner Reviewed-by: Nuno Sá Signed-off-by: Kurt Borja Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ade9000.c | 2 +- .../cros_ec_sensors/cros_ec_sensors_core.c | 5 +-- drivers/iio/health/max30100.c | 8 +--- drivers/iio/health/max30102.c | 2 +- drivers/iio/industrialio-core.c | 42 +------------------ drivers/iio/light/opt4060.c | 2 +- include/linux/iio/iio.h | 35 +++++++++++++++- 7 files changed, 39 insertions(+), 57 deletions(-) diff --git a/drivers/iio/adc/ade9000.c b/drivers/iio/adc/ade9000.c index 2de8a718d62af..db085dc5e5266 100644 --- a/drivers/iio/adc/ade9000.c +++ b/drivers/iio/adc/ade9000.c @@ -964,7 +964,7 @@ static irqreturn_t ade9000_dready_thread(int irq, void *data) struct iio_dev *indio_dev = data; /* Handle data ready interrupt from C4/EVENT/DREADY pin */ - if (!iio_device_claim_buffer_mode(indio_dev)) { + if (iio_device_try_claim_buffer_mode(indio_dev)) { ade9000_iio_push_buffer(indio_dev); iio_device_release_buffer_mode(indio_dev); } diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c index 9ac80e4b7d756..ef53066b1735b 100644 --- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c +++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c @@ -188,11 +188,8 @@ int cros_ec_sensors_push_data(struct iio_dev *indio_dev, /* * Ignore samples if the buffer is not set: it is needed if the ODR is * set but the buffer is not enabled yet. - * - * Note: iio_device_claim_buffer_mode() returns -EBUSY if the buffer - * is not enabled. */ - if (iio_device_claim_buffer_mode(indio_dev) < 0) + if (!iio_device_try_claim_buffer_mode(indio_dev)) return 0; out = (s16 *)st->samples; diff --git a/drivers/iio/health/max30100.c b/drivers/iio/health/max30100.c index 3d441013893c7..7dfdb5eb305eb 100644 --- a/drivers/iio/health/max30100.c +++ b/drivers/iio/health/max30100.c @@ -417,13 +417,7 @@ static int max30100_read_raw(struct iio_dev *indio_dev, * Temperature reading can only be acquired while engine * is running */ - if (iio_device_claim_buffer_mode(indio_dev)) { - /* - * Replacing -EBUSY or other error code - * returned by iio_device_claim_buffer_mode() - * because user space may rely on the current - * one. - */ + if (!iio_device_try_claim_buffer_mode(indio_dev)) { ret = -EAGAIN; } else { ret = max30100_get_temp(data, val); diff --git a/drivers/iio/health/max30102.c b/drivers/iio/health/max30102.c index a48c0881a4c72..6918fcb5de2bc 100644 --- a/drivers/iio/health/max30102.c +++ b/drivers/iio/health/max30102.c @@ -476,7 +476,7 @@ static int max30102_read_raw(struct iio_dev *indio_dev, * shutdown; leave shutdown briefly when buffer not running */ any_mode_retry: - if (iio_device_claim_buffer_mode(indio_dev)) { + if (!iio_device_try_claim_buffer_mode(indio_dev)) { /* * This one is a *bit* hacky. If we cannot claim buffer * mode, then try direct mode so that we make sure diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 0f8e3aa98b72f..3115d59c1372f 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -2183,7 +2183,7 @@ EXPORT_SYMBOL_GPL(__devm_iio_device_register); * * There are very few cases where a driver actually needs to lock the current * mode unconditionally. It's recommended to use iio_device_claim_direct() or - * iio_device_claim_buffer_mode() pairs or related helpers instead. + * iio_device_try_claim_buffer_mode() pairs or related helpers instead. */ void __iio_dev_mode_lock(struct iio_dev *indio_dev) { @@ -2201,46 +2201,6 @@ void __iio_dev_mode_unlock(struct iio_dev *indio_dev) } EXPORT_SYMBOL_GPL(__iio_dev_mode_unlock); -/** - * iio_device_claim_buffer_mode - Keep device in buffer mode - * @indio_dev: the iio_dev associated with the device - * - * If the device is in buffer mode it is guaranteed to stay - * that way until iio_device_release_buffer_mode() is called. - * - * Use with iio_device_release_buffer_mode(). - * - * Returns: 0 on success, -EBUSY on failure. - */ -int iio_device_claim_buffer_mode(struct iio_dev *indio_dev) -{ - struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); - - mutex_lock(&iio_dev_opaque->mlock); - - if (iio_buffer_enabled(indio_dev)) - return 0; - - mutex_unlock(&iio_dev_opaque->mlock); - return -EBUSY; -} -EXPORT_SYMBOL_GPL(iio_device_claim_buffer_mode); - -/** - * iio_device_release_buffer_mode - releases claim on buffer mode - * @indio_dev: the iio_dev associated with the device - * - * Release the claim. Device is no longer guaranteed to stay - * in buffer mode. - * - * Use with iio_device_claim_buffer_mode(). - */ -void iio_device_release_buffer_mode(struct iio_dev *indio_dev) -{ - mutex_unlock(&to_iio_dev_opaque(indio_dev)->mlock); -} -EXPORT_SYMBOL_GPL(iio_device_release_buffer_mode); - /** * iio_device_get_current_mode() - helper function providing read-only access to * the opaque @currentmode variable diff --git a/drivers/iio/light/opt4060.c b/drivers/iio/light/opt4060.c index 981c704e7df56..8c4a1f562a832 100644 --- a/drivers/iio/light/opt4060.c +++ b/drivers/iio/light/opt4060.c @@ -304,7 +304,7 @@ static int opt4060_set_driver_state(struct iio_dev *indio_dev, struct opt4060_chip *chip = iio_priv(indio_dev); int ret = 0; any_mode_retry: - if (iio_device_claim_buffer_mode(indio_dev)) { + if (!iio_device_try_claim_buffer_mode(indio_dev)) { /* * This one is a *bit* hacky. If we cannot claim buffer mode, * then try direct mode so that we make sure things cannot diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index e263ab5eeccf1..36bd14e93a75d 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -706,8 +706,39 @@ static inline bool iio_device_claim_direct(struct iio_dev *indio_dev) */ #define iio_device_release_direct(indio_dev) __iio_dev_mode_unlock(indio_dev) -int iio_device_claim_buffer_mode(struct iio_dev *indio_dev); -void iio_device_release_buffer_mode(struct iio_dev *indio_dev); +/** + * iio_device_try_claim_buffer_mode() - Keep device in buffer mode + * @indio_dev: the iio_dev associated with the device + * + * If the device is in buffer mode it is guaranteed to stay + * that way until iio_device_release_buffer_mode() is called. + * + * Use with iio_device_release_buffer_mode(). + * + * Returns: true on success, false on failure. + */ +static inline bool iio_device_try_claim_buffer_mode(struct iio_dev *indio_dev) +{ + __iio_dev_mode_lock(indio_dev); + + if (!iio_buffer_enabled(indio_dev)) { + __iio_dev_mode_unlock(indio_dev); + return false; + } + + return true; +} + +/** + * iio_device_release_buffer_mode() - releases claim on buffer mode + * @indio_dev: the iio_dev associated with the device + * + * Release the claim. Device is no longer guaranteed to stay + * in buffer mode. + * + * Use with iio_device_try_claim_buffer_mode(). + */ +#define iio_device_release_buffer_mode(indio_dev) __iio_dev_mode_unlock(indio_dev) extern const struct bus_type iio_bus_type; -- 2.47.3