Skip to content

Commit 702bf92

Browse files
committed
iio: adc: at91-sama5d2_adc: lock around oversampling and sample freq
In case of temperature sensor being available changes of oversampling ratio and sample frequency may be done (before/after reading the temperature) to improve the accuracy of the read temperature. As .read_raw()/.write_raw() could be called asynchronously from user space or other in kernel drivers concurrency on oversampling ratio and sample frequency existed before. Thus, to avoid concurrency on reading/updating oversampling ratio and sample frequency the st->lock was acquired/released accordingly. Fixes: 27e1771 ("iio:adc:at91_adc8xx: introduce new atmel adc driver") Fixes: 6794e23 ("iio: adc: at91-sama5d2_adc: add support for oversampling resolution") Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
1 parent 0f73cc6 commit 702bf92

1 file changed

Lines changed: 14 additions & 6 deletions

File tree

drivers/iio/adc/at91-sama5d2_adc.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1600,10 +1600,11 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
16001600
if (fn) {
16011601
ret = fn(st, chan->channel, &tmp_val);
16021602
*val = tmp_val;
1603+
ret = at91_adc_adjust_val_osr(st, val);
16031604
mutex_unlock(&st->lock);
16041605
iio_device_release_direct_mode(indio_dev);
16051606

1606-
return at91_adc_adjust_val_osr(st, val);
1607+
return ret;
16071608
}
16081609

16091610
/* in this case we have a voltage channel */
@@ -1659,11 +1660,15 @@ static int at91_adc_read_raw(struct iio_dev *indio_dev,
16591660
return IIO_VAL_FRACTIONAL_LOG2;
16601661

16611662
case IIO_CHAN_INFO_SAMP_FREQ:
1663+
mutex_lock(&st->lock);
16621664
*val = at91_adc_get_sample_freq(st);
1665+
mutex_unlock(&st->lock);
16631666
return IIO_VAL_INT;
16641667

16651668
case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
1669+
mutex_lock(&st->lock);
16661670
*val = st->oversampling_ratio;
1671+
mutex_unlock(&st->lock);
16671672
return IIO_VAL_INT;
16681673

16691674
default:
@@ -1676,7 +1681,7 @@ static int at91_adc_write_raw(struct iio_dev *indio_dev,
16761681
int val, int val2, long mask)
16771682
{
16781683
struct at91_adc_state *st = iio_priv(indio_dev);
1679-
int ret;
1684+
int ret = 0;
16801685

16811686
switch (mask) {
16821687
case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
@@ -1685,19 +1690,22 @@ static int at91_adc_write_raw(struct iio_dev *indio_dev,
16851690
(val != AT91_OSR_256SAMPLES))
16861691
return -EINVAL;
16871692
/* if no change, optimize out */
1693+
mutex_lock(&st->lock);
16881694
if (val == st->oversampling_ratio)
1689-
return 0;
1695+
goto unlock;
16901696
/* update ratio */
16911697
ret = at91_adc_config_emr(st, val);
1692-
if (ret)
1693-
return ret;
1694-
return 0;
1698+
unlock:
1699+
mutex_unlock(&st->lock);
1700+
return ret;
16951701
case IIO_CHAN_INFO_SAMP_FREQ:
16961702
if (val < st->soc_info.min_sample_rate ||
16971703
val > st->soc_info.max_sample_rate)
16981704
return -EINVAL;
16991705

1706+
mutex_lock(&st->lock);
17001707
at91_adc_setup_samp_freq(indio_dev, val);
1708+
mutex_unlock(&st->lock);
17011709
return 0;
17021710
default:
17031711
return -EINVAL;

0 commit comments

Comments
 (0)