Skip to content

Commit 40c48fb

Browse files
LorenzoBianconijic23
authored andcommitted
iio: common: st_sensors: fix possible infinite loop in st_sensors_irq_thread
Return a boolean value in st_sensors_new_samples_available routine in order to avoid an infinite loop in st_sensors_irq_thread if stat_drdy.addr is not defined or stat_drdy read fails Fixes: 90efe05 ("iio: st_sensors: harden interrupt handling") Reported-by: Jonathan Cameron <[email protected]> Signed-off-by: Lorenzo Bianconi <[email protected]> Reviewed-by: Linus Walleij <[email protected]> Link: https://lore.kernel.org/r/c9ec69ed349e7200c779fd7a5bf04c1aaa2817aa.1607438132.git.lorenzo@kernel.org Cc: <[email protected]> Signed-off-by: Jonathan Cameron <[email protected]>
1 parent efd597b commit 40c48fb

File tree

1 file changed

+17
-14
lines changed

1 file changed

+17
-14
lines changed

drivers/iio/common/st_sensors/st_sensors_trigger.c

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,35 +23,31 @@
2323
* @sdata: Sensor data.
2424
*
2525
* returns:
26-
* 0 - no new samples available
27-
* 1 - new samples available
28-
* negative - error or unknown
26+
* false - no new samples available or read error
27+
* true - new samples available
2928
*/
30-
static int st_sensors_new_samples_available(struct iio_dev *indio_dev,
31-
struct st_sensor_data *sdata)
29+
static bool st_sensors_new_samples_available(struct iio_dev *indio_dev,
30+
struct st_sensor_data *sdata)
3231
{
3332
int ret, status;
3433

3534
/* How would I know if I can't check it? */
3635
if (!sdata->sensor_settings->drdy_irq.stat_drdy.addr)
37-
return -EINVAL;
36+
return true;
3837

3938
/* No scan mask, no interrupt */
4039
if (!indio_dev->active_scan_mask)
41-
return 0;
40+
return false;
4241

4342
ret = regmap_read(sdata->regmap,
4443
sdata->sensor_settings->drdy_irq.stat_drdy.addr,
4544
&status);
4645
if (ret < 0) {
4746
dev_err(sdata->dev, "error checking samples available\n");
48-
return ret;
47+
return false;
4948
}
5049

51-
if (status & sdata->sensor_settings->drdy_irq.stat_drdy.mask)
52-
return 1;
53-
54-
return 0;
50+
return !!(status & sdata->sensor_settings->drdy_irq.stat_drdy.mask);
5551
}
5652

5753
/**
@@ -180,16 +176,23 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
180176

181177
/* Tell the interrupt handler that we're dealing with edges */
182178
if (irq_trig == IRQF_TRIGGER_FALLING ||
183-
irq_trig == IRQF_TRIGGER_RISING)
179+
irq_trig == IRQF_TRIGGER_RISING) {
180+
if (!sdata->sensor_settings->drdy_irq.stat_drdy.addr) {
181+
dev_err(&indio_dev->dev,
182+
"edge IRQ not supported w/o stat register.\n");
183+
err = -EOPNOTSUPP;
184+
goto iio_trigger_free;
185+
}
184186
sdata->edge_irq = true;
185-
else
187+
} else {
186188
/*
187189
* If we're not using edges (i.e. level interrupts) we
188190
* just mask off the IRQ, handle one interrupt, then
189191
* if the line is still low, we return to the
190192
* interrupt handler top half again and start over.
191193
*/
192194
irq_trig |= IRQF_ONESHOT;
195+
}
193196

194197
/*
195198
* If the interrupt pin is Open Drain, by definition this

0 commit comments

Comments
 (0)