Merge tag 'iio-fixes-for-4.17a' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 9 May 2018 15:08:29 +0000 (17:08 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 9 May 2018 15:08:29 +0000 (17:08 +0200)
Jonathan writes:

First round of IIO fixes for the 4.17 cycle.

* core
  - fix up some issues with overflow etc around wrong types
    for some fo the kfifo handling functions.  Seems unlikely
    this would be triggered in reality but the fixes are simple
    so let's tidy them up.  Second patch deals with checking
    the userspace value passed for length for potential overflow.
* ad7793
  - Catch up with changes to the ad_sigma_delta core and use
    read_raw / write_raw iwth IIO_CHAN_INFO_SAMP_FEW to handle
    sampling frequency control.
* at91-sama5d2
  - Channel config for differential channels was completely broken.
  - Missing Kconfig dependency for buffer support.
* hid-sensor
  - Fix an issue with powering up after resume due to wrong reference
    counting.
* stm32-dfsdm
  - Fix an issue with second writes of the oversampling settings
    failing.
  - Fix an issue with the sample rate being set to half of requested
    value when particular clock source is used.

drivers/iio/adc/Kconfig
drivers/iio/adc/ad7793.c
drivers/iio/adc/at91-sama5d2_adc.c
drivers/iio/adc/stm32-dfsdm-adc.c
drivers/iio/buffer/industrialio-buffer-dma.c
drivers/iio/buffer/kfifo_buf.c
drivers/iio/common/hid-sensors/hid-sensor-trigger.c
include/linux/iio/buffer_impl.h

index 15606f237480dacbd00a151d6a76d86e0107e5e9..9da79070357c7d932fc5804c9276737d2c89e18c 100644 (file)
@@ -158,6 +158,7 @@ config AT91_SAMA5D2_ADC
        depends on ARCH_AT91 || COMPILE_TEST
        depends on HAS_IOMEM
        depends on HAS_DMA
+       select IIO_BUFFER
        select IIO_TRIGGERED_BUFFER
        help
          Say yes here to build support for Atmel SAMA5D2 ADC which is
index 801afb61310bb171f317bbbb245b8ed9f8376f09..d4bbe5b533189730437aa5a8a4c8593288fc10da 100644 (file)
@@ -348,55 +348,6 @@ static const u16 ad7793_sample_freq_avail[16] = {0, 470, 242, 123, 62, 50, 39,
 static const u16 ad7797_sample_freq_avail[16] = {0, 0, 0, 123, 62, 50, 0,
                                        33, 0, 17, 16, 12, 10, 8, 6, 4};
 
-static ssize_t ad7793_read_frequency(struct device *dev,
-               struct device_attribute *attr,
-               char *buf)
-{
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct ad7793_state *st = iio_priv(indio_dev);
-
-       return sprintf(buf, "%d\n",
-              st->chip_info->sample_freq_avail[AD7793_MODE_RATE(st->mode)]);
-}
-
-static ssize_t ad7793_write_frequency(struct device *dev,
-               struct device_attribute *attr,
-               const char *buf,
-               size_t len)
-{
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct ad7793_state *st = iio_priv(indio_dev);
-       long lval;
-       int i, ret;
-
-       ret = kstrtol(buf, 10, &lval);
-       if (ret)
-               return ret;
-
-       if (lval == 0)
-               return -EINVAL;
-
-       for (i = 0; i < 16; i++)
-               if (lval == st->chip_info->sample_freq_avail[i])
-                       break;
-       if (i == 16)
-               return -EINVAL;
-
-       ret = iio_device_claim_direct_mode(indio_dev);
-       if (ret)
-               return ret;
-       st->mode &= ~AD7793_MODE_RATE(-1);
-       st->mode |= AD7793_MODE_RATE(i);
-       ad_sd_write_reg(&st->sd, AD7793_REG_MODE, sizeof(st->mode), st->mode);
-       iio_device_release_direct_mode(indio_dev);
-
-       return len;
-}
-
-static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
-               ad7793_read_frequency,
-               ad7793_write_frequency);
-
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
        "470 242 123 62 50 39 33 19 17 16 12 10 8 6 4");
 
@@ -424,7 +375,6 @@ static IIO_DEVICE_ATTR_NAMED(in_m_in_scale_available,
                ad7793_show_scale_available, NULL, 0);
 
 static struct attribute *ad7793_attributes[] = {
-       &iio_dev_attr_sampling_frequency.dev_attr.attr,
        &iio_const_attr_sampling_frequency_available.dev_attr.attr,
        &iio_dev_attr_in_m_in_scale_available.dev_attr.attr,
        NULL
@@ -435,7 +385,6 @@ static const struct attribute_group ad7793_attribute_group = {
 };
 
 static struct attribute *ad7797_attributes[] = {
-       &iio_dev_attr_sampling_frequency.dev_attr.attr,
        &iio_const_attr_sampling_frequency_available_ad7797.dev_attr.attr,
        NULL
 };
@@ -505,6 +454,10 @@ static int ad7793_read_raw(struct iio_dev *indio_dev,
                        *val -= offset;
                }
                return IIO_VAL_INT;
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               *val = st->chip_info
+                              ->sample_freq_avail[AD7793_MODE_RATE(st->mode)];
+               return IIO_VAL_INT;
        }
        return -EINVAL;
 }
@@ -542,6 +495,26 @@ static int ad7793_write_raw(struct iio_dev *indio_dev,
                                break;
                        }
                break;
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               if (!val) {
+                       ret = -EINVAL;
+                       break;
+               }
+
+               for (i = 0; i < 16; i++)
+                       if (val == st->chip_info->sample_freq_avail[i])
+                               break;
+
+               if (i == 16) {
+                       ret = -EINVAL;
+                       break;
+               }
+
+               st->mode &= ~AD7793_MODE_RATE(-1);
+               st->mode |= AD7793_MODE_RATE(i);
+               ad_sd_write_reg(&st->sd, AD7793_REG_MODE, sizeof(st->mode),
+                               st->mode);
+               break;
        default:
                ret = -EINVAL;
        }
index 4eff8351ce2994c51483964f2b4345e57b2e7056..8729d6524b4dbdb2b03a07e1ce5241ec2e5b2aaf 100644 (file)
@@ -333,6 +333,27 @@ static const struct iio_chan_spec at91_adc_channels[] = {
                                + AT91_SAMA5D2_DIFF_CHAN_CNT + 1),
 };
 
+static int at91_adc_chan_xlate(struct iio_dev *indio_dev, int chan)
+{
+       int i;
+
+       for (i = 0; i < indio_dev->num_channels; i++) {
+               if (indio_dev->channels[i].scan_index == chan)
+                       return i;
+       }
+       return -EINVAL;
+}
+
+static inline struct iio_chan_spec const *
+at91_adc_chan_get(struct iio_dev *indio_dev, int chan)
+{
+       int index = at91_adc_chan_xlate(indio_dev, chan);
+
+       if (index < 0)
+               return NULL;
+       return indio_dev->channels + index;
+}
+
 static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
 {
        struct iio_dev *indio = iio_trigger_get_drvdata(trig);
@@ -350,8 +371,10 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
        at91_adc_writel(st, AT91_SAMA5D2_TRGR, status);
 
        for_each_set_bit(bit, indio->active_scan_mask, indio->num_channels) {
-               struct iio_chan_spec const *chan = indio->channels + bit;
+               struct iio_chan_spec const *chan = at91_adc_chan_get(indio, bit);
 
+               if (!chan)
+                       continue;
                if (state) {
                        at91_adc_writel(st, AT91_SAMA5D2_CHER,
                                        BIT(chan->channel));
@@ -448,7 +471,11 @@ static int at91_adc_dma_start(struct iio_dev *indio_dev)
 
        for_each_set_bit(bit, indio_dev->active_scan_mask,
                         indio_dev->num_channels) {
-               struct iio_chan_spec const *chan = indio_dev->channels + bit;
+               struct iio_chan_spec const *chan =
+                                        at91_adc_chan_get(indio_dev, bit);
+
+               if (!chan)
+                       continue;
 
                st->dma_st.rx_buf_sz += chan->scan_type.storagebits / 8;
        }
@@ -526,8 +553,11 @@ static int at91_adc_buffer_predisable(struct iio_dev *indio_dev)
         */
        for_each_set_bit(bit, indio_dev->active_scan_mask,
                         indio_dev->num_channels) {
-               struct iio_chan_spec const *chan = indio_dev->channels + bit;
+               struct iio_chan_spec const *chan =
+                                       at91_adc_chan_get(indio_dev, bit);
 
+               if (!chan)
+                       continue;
                if (st->dma_st.dma_chan)
                        at91_adc_readl(st, chan->address);
        }
@@ -587,8 +617,11 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev,
 
        for_each_set_bit(bit, indio_dev->active_scan_mask,
                         indio_dev->num_channels) {
-               struct iio_chan_spec const *chan = indio_dev->channels + bit;
+               struct iio_chan_spec const *chan =
+                                       at91_adc_chan_get(indio_dev, bit);
 
+               if (!chan)
+                       continue;
                st->buffer[i] = at91_adc_readl(st, chan->address);
                i++;
        }
index 01422d11753cf39be105b9352e06746927d75731..b28a716a23b279420c2b819f59c32a135e37645c 100644 (file)
@@ -144,6 +144,7 @@ static int stm32_dfsdm_set_osrs(struct stm32_dfsdm_filter *fl,
         * Leave as soon as if exact resolution if reached.
         * Otherwise the higher resolution below 32 bits is kept.
         */
+       fl->res = 0;
        for (fosr = 1; fosr <= DFSDM_MAX_FL_OVERSAMPLING; fosr++) {
                for (iosr = 1; iosr <= DFSDM_MAX_INT_OVERSAMPLING; iosr++) {
                        if (fast)
@@ -193,7 +194,7 @@ static int stm32_dfsdm_set_osrs(struct stm32_dfsdm_filter *fl,
                }
        }
 
-       if (!fl->fosr)
+       if (!fl->res)
                return -EINVAL;
 
        return 0;
@@ -770,7 +771,7 @@ static int stm32_dfsdm_write_raw(struct iio_dev *indio_dev,
        struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
        struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id];
        struct stm32_dfsdm_channel *ch = &adc->dfsdm->ch_list[chan->channel];
-       unsigned int spi_freq = adc->spi_freq;
+       unsigned int spi_freq;
        int ret = -EINVAL;
 
        switch (mask) {
@@ -784,8 +785,18 @@ static int stm32_dfsdm_write_raw(struct iio_dev *indio_dev,
        case IIO_CHAN_INFO_SAMP_FREQ:
                if (!val)
                        return -EINVAL;
-               if (ch->src != DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL)
+
+               switch (ch->src) {
+               case DFSDM_CHANNEL_SPI_CLOCK_INTERNAL:
                        spi_freq = adc->dfsdm->spi_master_freq;
+                       break;
+               case DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_FALLING:
+               case DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_RISING:
+                       spi_freq = adc->dfsdm->spi_master_freq / 2;
+                       break;
+               default:
+                       spi_freq = adc->spi_freq;
+               }
 
                if (spi_freq % val)
                        dev_warn(&indio_dev->dev,
index 05e0c353e08984d370fe394a5f5139df5b67d486..b32bf57910caeffad07736600b974ec94afc17f2 100644 (file)
@@ -587,7 +587,7 @@ EXPORT_SYMBOL_GPL(iio_dma_buffer_set_bytes_per_datum);
  * Should be used as the set_length callback for iio_buffer_access_ops
  * struct for DMA buffers.
  */
-int iio_dma_buffer_set_length(struct iio_buffer *buffer, int length)
+int iio_dma_buffer_set_length(struct iio_buffer *buffer, unsigned int length)
 {
        /* Avoid an invalid state */
        if (length < 2)
index 047fe757ab97d6075bc920511a187dde78450b75..70c302a93d7fd3d7f8b884840c487bbcb7d2c532 100644 (file)
@@ -22,11 +22,18 @@ struct iio_kfifo {
 #define iio_to_kfifo(r) container_of(r, struct iio_kfifo, buffer)
 
 static inline int __iio_allocate_kfifo(struct iio_kfifo *buf,
-                               int bytes_per_datum, int length)
+                       size_t bytes_per_datum, unsigned int length)
 {
        if ((length == 0) || (bytes_per_datum == 0))
                return -EINVAL;
 
+       /*
+        * Make sure we don't overflow an unsigned int after kfifo rounds up to
+        * the next power of 2.
+        */
+       if (roundup_pow_of_two(length) > UINT_MAX / bytes_per_datum)
+               return -EINVAL;
+
        return __kfifo_alloc((struct __kfifo *)&buf->kf, length,
                             bytes_per_datum, GFP_KERNEL);
 }
@@ -67,7 +74,7 @@ static int iio_set_bytes_per_datum_kfifo(struct iio_buffer *r, size_t bpd)
        return 0;
 }
 
-static int iio_set_length_kfifo(struct iio_buffer *r, int length)
+static int iio_set_length_kfifo(struct iio_buffer *r, unsigned int length)
 {
        /* Avoid an invalid state */
        if (length < 2)
index cfb6588565ba2fddea55bbc97bdf60c9e14ea1b8..4905a997a7ec1feed21428e5acc28ef6e97f22d1 100644 (file)
@@ -178,14 +178,14 @@ int hid_sensor_power_state(struct hid_sensor_common *st, bool state)
 #ifdef CONFIG_PM
        int ret;
 
-       atomic_set(&st->user_requested_state, state);
-
        if (atomic_add_unless(&st->runtime_pm_enable, 1, 1))
                pm_runtime_enable(&st->pdev->dev);
 
-       if (state)
+       if (state) {
+               atomic_inc(&st->user_requested_state);
                ret = pm_runtime_get_sync(&st->pdev->dev);
-       else {
+       } else {
+               atomic_dec(&st->user_requested_state);
                pm_runtime_mark_last_busy(&st->pdev->dev);
                pm_runtime_use_autosuspend(&st->pdev->dev);
                ret = pm_runtime_put_autosuspend(&st->pdev->dev);
index b9e22b7e2f2884fe6c2f473c1c3e8baefe61e469..d1171db23742733244aaba3864bdfcfc2cab06fd 100644 (file)
@@ -53,7 +53,7 @@ struct iio_buffer_access_funcs {
        int (*request_update)(struct iio_buffer *buffer);
 
        int (*set_bytes_per_datum)(struct iio_buffer *buffer, size_t bpd);
-       int (*set_length)(struct iio_buffer *buffer, int length);
+       int (*set_length)(struct iio_buffer *buffer, unsigned int length);
 
        int (*enable)(struct iio_buffer *buffer, struct iio_dev *indio_dev);
        int (*disable)(struct iio_buffer *buffer, struct iio_dev *indio_dev);
@@ -72,10 +72,10 @@ struct iio_buffer_access_funcs {
  */
 struct iio_buffer {
        /** @length: Number of datums in buffer. */
-       int length;
+       unsigned int length;
 
        /**  @bytes_per_datum: Size of individual datum including timestamp. */
-       int bytes_per_datum;
+       size_t bytes_per_datum;
 
        /**
         * @access: Buffer access functions associated with the