iio: light: ltr501: claim direct mode during raw writes
authorAlison Schofield <amsfield22@gmail.com>
Sun, 16 Oct 2016 05:02:19 +0000 (22:02 -0700)
committerJonathan Cameron <jic23@kernel.org>
Sun, 23 Oct 2016 18:34:08 +0000 (19:34 +0100)
Driver was checking for direct mode but not locking it.  Use
claim/release helper functions to guarantee the device stays
in direct mode during all raw write operations.

Signed-off-by: Alison Schofield <amsfield22@gmail.com>
Acked-by: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
drivers/iio/light/ltr501.c

index d57747771197ef4d8f62152cf3760d06582cc518..b30e0c1c6cc4b70eecab00d4ae49b616a26a7e94 100644 (file)
@@ -739,8 +739,9 @@ static int ltr501_write_raw(struct iio_dev *indio_dev,
        int i, ret, freq_val, freq_val2;
        struct ltr501_chip_info *info = data->chip_info;
 
-       if (iio_buffer_enabled(indio_dev))
-               return -EBUSY;
+       ret = iio_device_claim_direct_mode(indio_dev);
+       if (ret)
+               return ret;
 
        switch (mask) {
        case IIO_CHAN_INFO_SCALE:
@@ -749,85 +750,105 @@ static int ltr501_write_raw(struct iio_dev *indio_dev,
                        i = ltr501_get_gain_index(info->als_gain,
                                                  info->als_gain_tbl_size,
                                                  val, val2);
-                       if (i < 0)
-                               return -EINVAL;
+                       if (i < 0) {
+                               ret = -EINVAL;
+                               break;
+                       }
 
                        data->als_contr &= ~info->als_gain_mask;
                        data->als_contr |= i << info->als_gain_shift;
 
-                       return regmap_write(data->regmap, LTR501_ALS_CONTR,
-                                           data->als_contr);
+                       ret = regmap_write(data->regmap, LTR501_ALS_CONTR,
+                                          data->als_contr);
+                       break;
                case IIO_PROXIMITY:
                        i = ltr501_get_gain_index(info->ps_gain,
                                                  info->ps_gain_tbl_size,
                                                  val, val2);
-                       if (i < 0)
-                               return -EINVAL;
+                       if (i < 0) {
+                               ret = -EINVAL;
+                               break;
+                       }
                        data->ps_contr &= ~LTR501_CONTR_PS_GAIN_MASK;
                        data->ps_contr |= i << LTR501_CONTR_PS_GAIN_SHIFT;
 
-                       return regmap_write(data->regmap, LTR501_PS_CONTR,
-                                           data->ps_contr);
+                       ret = regmap_write(data->regmap, LTR501_PS_CONTR,
+                                          data->ps_contr);
+                       break;
                default:
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       break;
                }
+               break;
+
        case IIO_CHAN_INFO_INT_TIME:
                switch (chan->type) {
                case IIO_INTENSITY:
-                       if (val != 0)
-                               return -EINVAL;
+                       if (val != 0) {
+                               ret = -EINVAL;
+                               break;
+                       }
                        mutex_lock(&data->lock_als);
-                       i = ltr501_set_it_time(data, val2);
+                       ret = ltr501_set_it_time(data, val2);
                        mutex_unlock(&data->lock_als);
-                       return i;
+                       break;
                default:
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       break;
                }
+               break;
+
        case IIO_CHAN_INFO_SAMP_FREQ:
                switch (chan->type) {
                case IIO_INTENSITY:
                        ret = ltr501_als_read_samp_freq(data, &freq_val,
                                                        &freq_val2);
                        if (ret < 0)
-                               return ret;
+                               break;
 
                        ret = ltr501_als_write_samp_freq(data, val, val2);
                        if (ret < 0)
-                               return ret;
+                               break;
 
                        /* update persistence count when changing frequency */
                        ret = ltr501_write_intr_prst(data, chan->type,
                                                     0, data->als_period);
 
                        if (ret < 0)
-                               return ltr501_als_write_samp_freq(data,
-                                                                 freq_val,
-                                                                 freq_val2);
-                       return ret;
+                               ret = ltr501_als_write_samp_freq(data, freq_val,
+                                                                freq_val2);
+                       break;
                case IIO_PROXIMITY:
                        ret = ltr501_ps_read_samp_freq(data, &freq_val,
                                                       &freq_val2);
                        if (ret < 0)
-                               return ret;
+                               break;
 
                        ret = ltr501_ps_write_samp_freq(data, val, val2);
                        if (ret < 0)
-                               return ret;
+                               break;
 
                        /* update persistence count when changing frequency */
                        ret = ltr501_write_intr_prst(data, chan->type,
                                                     0, data->ps_period);
 
                        if (ret < 0)
-                               return ltr501_ps_write_samp_freq(data,
-                                                                freq_val,
-                                                                freq_val2);
-                       return ret;
+                               ret = ltr501_ps_write_samp_freq(data, freq_val,
+                                                               freq_val2);
+                       break;
                default:
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       break;
                }
+               break;
+
+       default:
+               ret = -EINVAL;
+               break;
        }
-       return -EINVAL;
+
+       iio_device_release_direct_mode(indio_dev);
+       return ret;
 }
 
 static int ltr501_read_thresh(struct iio_dev *indio_dev,