summaryrefslogtreecommitdiff
path: root/include/linux/iio/adc
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@baylibre.com>2024-12-06 18:28:38 +0100
committerJonathan Cameron <Jonathan.Cameron@huawei.com>2024-12-11 19:20:48 +0000
commitf522589c139debb8af56dbead0c6e9dfca2d5ce4 (patch)
treed68f540610ee06a5f5d43f4a3921846b8887dd8c /include/linux/iio/adc
parent90b8b2fe60eb673d917b3c11abfc0a8ee144145e (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.h1
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;