iio: light: vcnl4000: Switch to sparse friendly iio_device_claim/release_direct()
authorJonathan Cameron <Jonathan.Cameron@huawei.com>
Sun, 9 Mar 2025 17:06:32 +0000 (17:06 +0000)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Tue, 22 Apr 2025 18:09:56 +0000 (19:09 +0100)
These new functions allow sparse to find failures to release
direct mode reducing chances of bugs over the claim_direct_mode()
functions that are deprecated.

To simplify the code whilst making the change (and avoid potential false
positives from sparse), split the enabling and disabling of thresholds
into separate functions.  This could have been done in two steps
by splitting the functions first, but would have meant rewriting
the enable function twice.

Cc: Astrid Rost <astrid.rost@axis.com>
Tested-by: Per-Daniel Olsson <perdaniel.olsson@axis.com>
Reviewed-by: Per-Daniel Olsson <perdaniel.olsson@axis.com>
Reviewed-by: David Lechner <dlechner@baylibre.com>
Link: https://patch.msgid.link/20250309170633.1347476-18-jic23@kernel.org
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/light/vcnl4000.c

index e19199b17f2ef7ebd022c211605418711b8220d2..d7489bee2dffaf400327da7aa1ef4d1a12657e09 100644 (file)
@@ -1084,9 +1084,8 @@ static int vcnl4010_read_raw(struct iio_dev *indio_dev,
        switch (mask) {
        case IIO_CHAN_INFO_RAW:
        case IIO_CHAN_INFO_SCALE:
-               ret = iio_device_claim_direct_mode(indio_dev);
-               if (ret)
-                       return ret;
+               if (!iio_device_claim_direct(indio_dev))
+                       return -EBUSY;
 
                /* Protect against event capture. */
                if (vcnl4010_is_in_periodic_mode(data)) {
@@ -1096,7 +1095,7 @@ static int vcnl4010_read_raw(struct iio_dev *indio_dev,
                                                mask);
                }
 
-               iio_device_release_direct_mode(indio_dev);
+               iio_device_release_direct(indio_dev);
                return ret;
        case IIO_CHAN_INFO_SAMP_FREQ:
                switch (chan->type) {
@@ -1157,9 +1156,8 @@ static int vcnl4010_write_raw(struct iio_dev *indio_dev,
        int ret;
        struct vcnl4000_data *data = iio_priv(indio_dev);
 
-       ret = iio_device_claim_direct_mode(indio_dev);
-       if (ret)
-               return ret;
+       if (!iio_device_claim_direct(indio_dev))
+               return -EBUSY;
 
        /* Protect against event capture. */
        if (vcnl4010_is_in_periodic_mode(data)) {
@@ -1183,7 +1181,7 @@ static int vcnl4010_write_raw(struct iio_dev *indio_dev,
        }
 
 end:
-       iio_device_release_direct_mode(indio_dev);
+       iio_device_release_direct(indio_dev);
        return ret;
 }
 
@@ -1410,46 +1408,52 @@ static int vcnl4010_read_event_config(struct iio_dev *indio_dev,
        }
 }
 
-static int vcnl4010_config_threshold(struct iio_dev *indio_dev, bool state)
+static int vcnl4010_config_threshold_enable(struct vcnl4000_data *data)
 {
-       struct vcnl4000_data *data = iio_priv(indio_dev);
        int ret;
-       int icr;
-       int command;
 
-       if (state) {
-               ret = iio_device_claim_direct_mode(indio_dev);
-               if (ret)
-                       return ret;
+       /* Enable periodic measurement of proximity data. */
+       ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND,
+                                       VCNL4000_SELF_TIMED_EN | VCNL4000_PROX_EN);
+       if (ret < 0)
+               return ret;
 
-               /* Enable periodic measurement of proximity data. */
-               command = VCNL4000_SELF_TIMED_EN | VCNL4000_PROX_EN;
+       /*
+        * Enable interrupts on threshold, for proximity data by
+        * default.
+        */
+       return i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL,
+                                        VCNL4010_INT_THR_EN);
+}
 
-               /*
-                * Enable interrupts on threshold, for proximity data by
-                * default.
-                */
-               icr = VCNL4010_INT_THR_EN;
-       } else {
-               if (!vcnl4010_is_thr_enabled(data))
-                       return 0;
+static int vcnl4010_config_threshold_disable(struct vcnl4000_data *data)
+{
+       int ret;
 
-               command = 0;
-               icr = 0;
-       }
+       if (!vcnl4010_is_thr_enabled(data))
+               return 0;
 
-       ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND,
-                                       command);
+       ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, 0);
        if (ret < 0)
-               goto end;
+               return ret;
 
-       ret = i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, icr);
+       return i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, 0);
+}
 
-end:
-       if (state)
-               iio_device_release_direct_mode(indio_dev);
+static int vcnl4010_config_threshold(struct iio_dev *indio_dev, bool state)
+{
+       struct vcnl4000_data *data = iio_priv(indio_dev);
+       int ret;
 
-       return ret;
+       if (state) {
+               if (!iio_device_claim_direct(indio_dev))
+                       return -EBUSY;
+               ret = vcnl4010_config_threshold_enable(data);
+               iio_device_release_direct(indio_dev);
+               return ret;
+       } else {
+               return vcnl4010_config_threshold_disable(data);
+       }
 }
 
 static int vcnl4010_write_event_config(struct iio_dev *indio_dev,