From: David Frey <dpf...@gmail.com>

[ Upstream commit 82f3015635249a8c8c45bac303fd84905066f04f ]

When an end-of-conversion interrupt is received after performing a
single-shot reading of the light sensor, the driver was waking up the
result ready queue before checking opt->ok_to_ignore_lock to determine
if it should unlock the mutex. The problem occurred in the case where
the other thread woke up and changed the value of opt->ok_to_ignore_lock
to false prior to the interrupt thread performing its read of the
variable. In this case, the mutex would be unlocked twice.

Signed-off-by: David Frey <dpf...@gmail.com>
Reviewed-by: Andreas Dannenberg <dannenb...@ti.com>
Fixes: 94a9b7b1809f ("iio: light: add support for TI's opt3001 light sensor")
Cc: <sta...@vger.kernel.org>
Signed-off-by: Jonathan Cameron <jonathan.came...@huawei.com>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 drivers/iio/light/opt3001.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/light/opt3001.c b/drivers/iio/light/opt3001.c
index e666879007d2c..92004a2563ea8 100644
--- a/drivers/iio/light/opt3001.c
+++ b/drivers/iio/light/opt3001.c
@@ -686,6 +686,7 @@ static irqreturn_t opt3001_irq(int irq, void *_iio)
        struct iio_dev *iio = _iio;
        struct opt3001 *opt = iio_priv(iio);
        int ret;
+       bool wake_result_ready_queue = false;
 
        if (!opt->ok_to_ignore_lock)
                mutex_lock(&opt->lock);
@@ -720,13 +721,16 @@ static irqreturn_t opt3001_irq(int irq, void *_iio)
                }
                opt->result = ret;
                opt->result_ready = true;
-               wake_up(&opt->result_ready_queue);
+               wake_result_ready_queue = true;
        }
 
 out:
        if (!opt->ok_to_ignore_lock)
                mutex_unlock(&opt->lock);
 
+       if (wake_result_ready_queue)
+               wake_up(&opt->result_ready_queue);
+
        return IRQ_HANDLED;
 }
 
-- 
2.20.1

Reply via email to