iio: adc: stm32-adc: skip adc-channels setup if none is present
authorSean Nyekjaer <sean@geanix.com>
Wed, 3 May 2023 16:20:29 +0000 (18:20 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 9 Jun 2023 08:34:19 +0000 (10:34 +0200)
commit 3e27ef0ced49f8ae7883c25fadf76a2086e99025 upstream.

If only adc differential channels are defined driver will fail with
stm32-adc: probe of 48003000.adc:adc@0 failed with error -22

Fix this by skipping the initialization if no channels are defined.

This applies only to the legacy way of initializing adc channels.

Fixes: d7705f35448a ("iio: adc: stm32-adc: convert to device properties")
Signed-off-by: Sean Nyekjaer <sean@geanix.com>
Reviewed-by: Olivier Moysan <olivier.moysan@foss.st.com>
Link: https://lore.kernel.org/r/20230503162029.3654093-2-sean@geanix.com
Cc: <Stable@vger.kernel.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/iio/adc/stm32-adc.c

index 3cda529..b5d7ba2 100644 (file)
@@ -1913,6 +1913,7 @@ static int stm32_adc_legacy_chan_init(struct iio_dev *indio_dev,
        struct stm32_adc_diff_channel diff[STM32_ADC_CH_MAX];
        struct device *dev = &indio_dev->dev;
        u32 num_diff = adc->num_diff;
+       int num_se = nchans - num_diff;
        int size = num_diff * sizeof(*diff) / sizeof(u32);
        int scan_index = 0, ret, i, c;
        u32 smp = 0, smps[STM32_ADC_CH_MAX], chans[STM32_ADC_CH_MAX];
@@ -1939,29 +1940,32 @@ static int stm32_adc_legacy_chan_init(struct iio_dev *indio_dev,
                        scan_index++;
                }
        }
-
-       ret = device_property_read_u32_array(dev, "st,adc-channels", chans,
-                                            nchans);
-       if (ret)
-               return ret;
-
-       for (c = 0; c < nchans; c++) {
-               if (chans[c] >= adc_info->max_channels) {
-                       dev_err(&indio_dev->dev, "Invalid channel %d\n",
-                               chans[c]);
-                       return -EINVAL;
+       if (num_se > 0) {
+               ret = device_property_read_u32_array(dev, "st,adc-channels", chans, num_se);
+               if (ret) {
+                       dev_err(&indio_dev->dev, "Failed to get st,adc-channels %d\n", ret);
+                       return ret;
                }
 
-               /* Channel can't be configured both as single-ended & diff */
-               for (i = 0; i < num_diff; i++) {
-                       if (chans[c] == diff[i].vinp) {
-                               dev_err(&indio_dev->dev, "channel %d misconfigured\n",  chans[c]);
+               for (c = 0; c < num_se; c++) {
+                       if (chans[c] >= adc_info->max_channels) {
+                               dev_err(&indio_dev->dev, "Invalid channel %d\n",
+                                       chans[c]);
                                return -EINVAL;
                        }
+
+                       /* Channel can't be configured both as single-ended & diff */
+                       for (i = 0; i < num_diff; i++) {
+                               if (chans[c] == diff[i].vinp) {
+                                       dev_err(&indio_dev->dev, "channel %d misconfigured\n",
+                                               chans[c]);
+                                       return -EINVAL;
+                               }
+                       }
+                       stm32_adc_chan_init_one(indio_dev, &channels[scan_index],
+                                               chans[c], 0, scan_index, false);
+                       scan_index++;
                }
-               stm32_adc_chan_init_one(indio_dev, &channels[scan_index],
-                                       chans[c], 0, scan_index, false);
-               scan_index++;
        }
 
        if (adc->nsmps > 0) {
@@ -2153,7 +2157,7 @@ static int stm32_adc_chan_fw_init(struct iio_dev *indio_dev, bool timestamping)
 
        if (legacy)
                ret = stm32_adc_legacy_chan_init(indio_dev, adc, channels,
-                                                num_channels);
+                                                timestamping ? num_channels - 1 : num_channels);
        else
                ret = stm32_adc_generic_chan_init(indio_dev, adc, channels);
        if (ret < 0)