Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

iio: adc: stm32-adc: skip adc-channels setup if none is present

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>

authored by

Sean Nyekjaer and committed by
Jonathan Cameron
3e27ef0c 9c0d6ccd

+23 -19
+23 -19
drivers/iio/adc/stm32-adc.c
··· 2036 2036 struct stm32_adc_diff_channel diff[STM32_ADC_CH_MAX]; 2037 2037 struct device *dev = &indio_dev->dev; 2038 2038 u32 num_diff = adc->num_diff; 2039 + int num_se = nchans - num_diff; 2039 2040 int size = num_diff * sizeof(*diff) / sizeof(u32); 2040 2041 int scan_index = 0, ret, i, c; 2041 2042 u32 smp = 0, smps[STM32_ADC_CH_MAX], chans[STM32_ADC_CH_MAX]; ··· 2063 2062 scan_index++; 2064 2063 } 2065 2064 } 2066 - 2067 - ret = device_property_read_u32_array(dev, "st,adc-channels", chans, 2068 - nchans); 2069 - if (ret) 2070 - return ret; 2071 - 2072 - for (c = 0; c < nchans; c++) { 2073 - if (chans[c] >= adc_info->max_channels) { 2074 - dev_err(&indio_dev->dev, "Invalid channel %d\n", 2075 - chans[c]); 2076 - return -EINVAL; 2065 + if (num_se > 0) { 2066 + ret = device_property_read_u32_array(dev, "st,adc-channels", chans, num_se); 2067 + if (ret) { 2068 + dev_err(&indio_dev->dev, "Failed to get st,adc-channels %d\n", ret); 2069 + return ret; 2077 2070 } 2078 2071 2079 - /* Channel can't be configured both as single-ended & diff */ 2080 - for (i = 0; i < num_diff; i++) { 2081 - if (chans[c] == diff[i].vinp) { 2082 - dev_err(&indio_dev->dev, "channel %d misconfigured\n", chans[c]); 2072 + for (c = 0; c < num_se; c++) { 2073 + if (chans[c] >= adc_info->max_channels) { 2074 + dev_err(&indio_dev->dev, "Invalid channel %d\n", 2075 + chans[c]); 2083 2076 return -EINVAL; 2084 2077 } 2078 + 2079 + /* Channel can't be configured both as single-ended & diff */ 2080 + for (i = 0; i < num_diff; i++) { 2081 + if (chans[c] == diff[i].vinp) { 2082 + dev_err(&indio_dev->dev, "channel %d misconfigured\n", 2083 + chans[c]); 2084 + return -EINVAL; 2085 + } 2086 + } 2087 + stm32_adc_chan_init_one(indio_dev, &channels[scan_index], 2088 + chans[c], 0, scan_index, false); 2089 + scan_index++; 2085 2090 } 2086 - stm32_adc_chan_init_one(indio_dev, &channels[scan_index], 2087 - chans[c], 0, scan_index, false); 2088 - scan_index++; 2089 2091 } 2090 2092 2091 2093 if (adc->nsmps > 0) { ··· 2309 2305 2310 2306 if (legacy) 2311 2307 ret = stm32_adc_legacy_chan_init(indio_dev, adc, channels, 2312 - num_channels); 2308 + timestamping ? num_channels - 1 : num_channels); 2313 2309 else 2314 2310 ret = stm32_adc_generic_chan_init(indio_dev, adc, channels); 2315 2311 if (ret < 0)