diff options
| author | Uwe Kleine-König <u.kleine-koenig@baylibre.com> | 2024-12-06 18:28:38 +0100 |
|---|---|---|
| committer | Jonathan Cameron <Jonathan.Cameron@huawei.com> | 2024-12-11 19:20:48 +0000 |
| commit | f522589c139debb8af56dbead0c6e9dfca2d5ce4 (patch) | |
| tree | d68f540610ee06a5f5d43f4a3921846b8887dd8c /include/linux/iio/adc | |
| parent | 90b8b2fe60eb673d917b3c11abfc0a8ee144145e (diff) | |
iio: adc: ad_sigma_delta: Fix a race condition
The ad_sigma_delta driver helper uses irq_disable_nosync(). With that
one it is possible that the irq handler still runs after the
irq_disable_nosync() function call returns. Also to properly synchronize
irq disabling in the different threads proper locking is needed and
because it's unclear if the irq handler's irq_disable_nosync() call
comes first or the one in the enabler's error path, all code locations
that disable the irq must check for .irq_dis first to ensure there is
exactly one disable call per enable call.
So add a spinlock to the struct ad_sigma_delta and use it to synchronize
irq enabling and disabling. Also only act in the irq handler if the irq
is still enabled.
Fixes: af3008485ea0 ("iio:adc: Add common code for ADI Sigma Delta devices")
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
Link: https://patch.msgid.link/9e6def47e2e773e0e15b7a2c29d22629b53d91b1.1733504533.git.u.kleine-koenig@baylibre.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Diffstat (limited to 'include/linux/iio/adc')
| -rw-r--r-- | include/linux/iio/adc/ad_sigma_delta.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/include/linux/iio/adc/ad_sigma_delta.h b/include/linux/iio/adc/ad_sigma_delta.h index 895b7ebf4be5..200130e4244d 100644 --- a/include/linux/iio/adc/ad_sigma_delta.h +++ b/include/linux/iio/adc/ad_sigma_delta.h @@ -86,6 +86,7 @@ struct ad_sigma_delta { /* private: */ struct completion completion; + spinlock_t irq_lock; /* protects .irq_dis and irq en/disable state */ bool irq_dis; bool bus_locked; |
