summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStepan Ionichev <sozdayvek@gmail.com>2026-05-18 23:11:10 +0500
committerJonathan Cameron <jic23@kernel.org>2026-07-03 23:59:59 +0100
commitd07bf43d175a2be1371ef5460b3e8f8ba3d60bd7 (patch)
treeed4c0296002177937c77d878dcaeb75f09560191
parent331ca76fe5cee0df5a025d97d68fee53140053c7 (diff)
downloadlinux-stable-d07bf43d175a2be1371ef5460b3e8f8ba3d60bd7.tar.gz
linux-stable-d07bf43d175a2be1371ef5460b3e8f8ba3d60bd7.zip
iio: pressure: rohm-bm1390: harden trigger handler against transient errors
bm1390_trigger_handler() returns from three error paths without calling iio_trigger_notify_done(). The success path at the end does, so on a transient regmap or read failure the trigger's use_count is never decremented and iio_trigger_poll_chained() drops subsequent dispatches until the trigger is reattached. This is not a fix for a reported bug, only hardening against hardware or bus glitches; if a glitch is persistent the device is wedged and needs an unbind anyway, which is left to the user. Split the function so the inner helper returns bool with the data-read outcome, and the outer IRQ handler calls iio_trigger_notify_done() once and reports the result via IRQ_RETVAL(). Signed-off-by: Stepan Ionichev <sozdayvek@gmail.com> Reviewed-by: Matti Vaittinen <mazziesaccount@gmail.com> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
-rw-r--r--drivers/iio/pressure/rohm-bm1390.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/drivers/iio/pressure/rohm-bm1390.c b/drivers/iio/pressure/rohm-bm1390.c
index b3be9de03678..9d72ae64126c 100644
--- a/drivers/iio/pressure/rohm-bm1390.c
+++ b/drivers/iio/pressure/rohm-bm1390.c
@@ -621,17 +621,15 @@ static const struct iio_buffer_setup_ops bm1390_buffer_ops = {
.predisable = bm1390_buffer_predisable,
};
-static irqreturn_t bm1390_trigger_handler(int irq, void *p)
+static bool bm1390_handle_trigger(struct iio_dev *idev)
{
- struct iio_poll_func *pf = p;
- struct iio_dev *idev = pf->indio_dev;
struct bm1390_data *data = iio_priv(idev);
int ret, status;
/* DRDY is acked by reading status reg */
ret = regmap_read(data->regmap, BM1390_REG_STATUS, &status);
if (ret || !status)
- return IRQ_NONE;
+ return false;
dev_dbg(data->dev, "DRDY trig status 0x%x\n", status);
@@ -639,7 +637,7 @@ static irqreturn_t bm1390_trigger_handler(int irq, void *p)
ret = bm1390_pressure_read(data, &data->buf.pressure);
if (ret) {
dev_warn(data->dev, "sample read failed %d\n", ret);
- return IRQ_NONE;
+ return false;
}
}
@@ -648,15 +646,26 @@ static irqreturn_t bm1390_trigger_handler(int irq, void *p)
&data->buf.temp, sizeof(data->buf.temp));
if (ret) {
dev_warn(data->dev, "temp read failed %d\n", ret);
- return IRQ_HANDLED;
+ return true;
}
}
iio_push_to_buffers_with_ts(idev, &data->buf, sizeof(data->buf),
data->timestamp);
+
+ return true;
+}
+
+static irqreturn_t bm1390_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *idev = pf->indio_dev;
+ bool result;
+
+ result = bm1390_handle_trigger(idev);
iio_trigger_notify_done(idev->trig);
- return IRQ_HANDLED;
+ return IRQ_RETVAL(result);
}
/* Get timestamps and wake the thread if we need to read data */