[PATCH v2 2/5] iio: chemical: sgp40: Replace manual locking with guard()

From: Jaakko Koivisto

Date: Mon Nov 02 2026 - 04:16:57 EST


Replace manual mutex_lock() and mutex_unlock() with RAII-style
guard(mutex)().

Extend the lock in sgp40_measure_resistance_raw() to cover the
I2C send and receive cycle, preventing I/O-errors if the device
is currently running a command, or clobbering the output of a previous
command if a new command is issued during the sleep-period between
i2c_master_send() and i2c_master_recv().

Signed-off-by: Jaakko Koivisto <jmatko@xxxxxx>
---
drivers/iio/chemical/sgp40.c | 33 +++++++++++++--------------------
1 file changed, 13 insertions(+), 20 deletions(-)

diff --git a/drivers/iio/chemical/sgp40.c b/drivers/iio/chemical/sgp40.c
index 3a239fb6847f..080d51f9f53c 100644
--- a/drivers/iio/chemical/sgp40.c
+++ b/drivers/iio/chemical/sgp40.c
@@ -148,9 +148,8 @@ static int sgp40_calc_voc(struct sgp40_data *data, u16 resistance_raw, int *voc)
u32 exp = 0;

/* we calculate as a multiple of 16384 (2^14) */
- mutex_lock(&data->lock);
+ guard(mutex)(&data->lock);
x = ((int)resistance_raw - data->res_calibbias) * 106;
- mutex_unlock(&data->lock);

/* voc = 500 / (1 + e^x) */
exp = sgp40_exp(x, SGP40_CALC_POWER, 18);
@@ -172,7 +171,7 @@ static int sgp40_measure_resistance_raw(struct sgp40_data *data, u16 *resistance
struct sgp40_tg_measure tg = {.command = {0x26, 0x0F}};
struct sgp40_tg_result tgres;

- mutex_lock(&data->lock);
+ guard(mutex)(&data->lock);

ticks = (data->rht / 10) * 65535 / 10000;
ticks16 = (u16)clamp(ticks, 0u, 65535u); /* clamp between 0 .. 100 %rH */
@@ -184,8 +183,6 @@ static int sgp40_measure_resistance_raw(struct sgp40_data *data, u16 *resistance
tg.temp_ticks = cpu_to_be16(ticks16);
tg.temp_crc = crc8(sgp40_crc8_table, (u8 *)&tg.temp_ticks, 2, SGP40_CRC8_INIT);

- mutex_unlock(&data->lock);
-
ret = i2c_master_send(client, (const char *)&tg, sizeof(tg));
if (ret < 0)
return ret;
@@ -232,16 +229,16 @@ static int sgp40_read_raw(struct iio_dev *indio_dev,

*val = resistance_raw;
return IIO_VAL_INT;
- case IIO_TEMP:
- mutex_lock(&data->lock);
+ case IIO_TEMP: {
+ guard(mutex)(&data->lock);
*val = data->temp;
- mutex_unlock(&data->lock);
return IIO_VAL_INT;
- case IIO_HUMIDITYRELATIVE:
- mutex_lock(&data->lock);
+ }
+ case IIO_HUMIDITYRELATIVE: {
+ guard(mutex)(&data->lock);
*val = data->rht;
- mutex_unlock(&data->lock);
return IIO_VAL_INT;
+ }
default:
return -EINVAL;
}
@@ -263,11 +260,11 @@ static int sgp40_read_raw(struct iio_dev *indio_dev,
*val2 = ((voc % (1 << SGP40_CALC_POWER)) * 244) / (1 << (SGP40_CALC_POWER - 12));
dev_dbg(data->dev, "voc: %d val: %d.%06d\n", voc, *val, *val2);
return IIO_VAL_INT_PLUS_MICRO;
- case IIO_CHAN_INFO_CALIBBIAS:
- mutex_lock(&data->lock);
+ case IIO_CHAN_INFO_CALIBBIAS: {
+ guard(mutex)(&data->lock);
*val = data->res_calibbias;
- mutex_unlock(&data->lock);
return IIO_VAL_INT;
+ }
default:
return -EINVAL;
}
@@ -279,6 +276,8 @@ static int sgp40_write_raw(struct iio_dev *indio_dev,
{
struct sgp40_data *data = iio_priv(indio_dev);

+ guard(mutex)(&data->lock);
+
switch (mask) {
case IIO_CHAN_INFO_RAW:
switch (chan->type) {
@@ -286,17 +285,13 @@ static int sgp40_write_raw(struct iio_dev *indio_dev,
if ((val < -45000) || (val > 130000))
return -EINVAL;

- mutex_lock(&data->lock);
data->temp = val;
- mutex_unlock(&data->lock);
return 0;
case IIO_HUMIDITYRELATIVE:
if ((val < 0) || (val > 100000))
return -EINVAL;

- mutex_lock(&data->lock);
data->rht = val;
- mutex_unlock(&data->lock);
return 0;
default:
return -EINVAL;
@@ -305,9 +300,7 @@ static int sgp40_write_raw(struct iio_dev *indio_dev,
if ((val < 20000) || (val > 52768))
return -EINVAL;

- mutex_lock(&data->lock);
data->res_calibbias = val;
- mutex_unlock(&data->lock);
return 0;
}
return -EINVAL;
--
2.56.0