mirror of
https://github.com/torvalds/linux.git
synced 2026-09-25 17:42:03 +02:00
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>
This commit is contained in:
parent
331ca76fe5
commit
d07bf43d17
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user