diff options
| author | Stepan Ionichev <sozdayvek@gmail.com> | 2026-05-18 23:11:10 +0500 |
|---|---|---|
| committer | Jonathan Cameron <jic23@kernel.org> | 2026-07-03 23:59:59 +0100 |
| commit | d07bf43d175a2be1371ef5460b3e8f8ba3d60bd7 (patch) | |
| tree | ed4c0296002177937c77d878dcaeb75f09560191 | |
| parent | 331ca76fe5cee0df5a025d97d68fee53140053c7 (diff) | |
| download | linux-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.c | 23 |
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 */ |
