iio: light: si1133: prevent race condition on timeout

Sashiko reported a bug where the si1133_command exits on timeout
without halting the sensor or masking the interrupt. If the sensor
completes the command later, any subsequent command to the sensor
will cause the IRQ handler to complete immediately, returning stale
data to the driver all while the command hasn't finished yet, shifting
all potential reads in the future.

Fix this by masking the IRQ if wait_for_completion_timeout() fails.
When initiating a new command, do a dummy read of the IRQ_STATUS
register and turn the IRQ back on.

Fixes: e01e7eaf37 ("iio: light: introduce si1133")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/message/20260428-si1133-checkup-v2-5-70ad14bfefe2%40gmail.com
Assisted-by: gemini:gemini-3.1-pro-preview
Signed-off-by: Joshua Crofts <joshua.crofts1@gmail.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
This commit is contained in:
Joshua Crofts 2026-05-05 09:31:27 +02:00 committed by Jonathan Cameron
parent 0a5f45ed23
commit 8c50a95ceb

View File

@ -395,8 +395,14 @@ static int si1133_command(struct si1133_data *data, u8 cmd)
expected_seq = (data->rsp_seq + 1) & SI1133_MAX_CMD_CTR;
if (cmd == SI1133_CMD_FORCE)
if (cmd == SI1133_CMD_FORCE) {
/* Flush pending IRQs from a previous timeout. */
regmap_read(data->regmap, SI1133_REG_IRQ_STATUS, &resp);
regmap_write(data->regmap, SI1133_REG_IRQ_ENABLE,
SI1133_IRQ_CHANNEL_ENABLE);
reinit_completion(&data->completion);
}
err = regmap_write(data->regmap, SI1133_REG_COMMAND, cmd);
if (err) {
@ -409,6 +415,7 @@ static int si1133_command(struct si1133_data *data, u8 cmd)
/* wait for irq */
if (!wait_for_completion_timeout(&data->completion,
msecs_to_jiffies(SI1133_COMPLETION_TIMEOUT_MS))) {
regmap_write(data->regmap, SI1133_REG_IRQ_ENABLE, 0);
err = -ETIMEDOUT;
goto out;
}