Skip to content

Commit 3f9bce7

Browse files
LorenzoBianconijic23
authored andcommitted
iio: imu: st_lsm6dsx: fix edge-trigger interrupts
If we are using edge IRQs, new samples can arrive while processing current interrupt since there are no hw guarantees the irq line stays "low" long enough to properly detect the new interrupt. In this case the new sample will be missed. Polling FIFO status register in st_lsm6dsx_handler_thread routine allow us to read new samples even if the interrupt arrives while processing previous data and the timeslot where the line is "low" is too short to be properly detected. Fixes: 89ca88a ("iio: imu: st_lsm6dsx: support active-low interrupts") Fixes: 290a6ce ("iio: imu: add support to lsm6dsx driver") Signed-off-by: Lorenzo Bianconi <[email protected]> Link: https://lore.kernel.org/r/5e93cda7dc1e665f5685c53ad8e9ea71dbae782d.1605378871.git.lorenzo@kernel.org Cc: <[email protected]> Signed-off-by: Jonathan Cameron <[email protected]>
1 parent 3418bd7 commit 3f9bce7

File tree

1 file changed

+21
-5
lines changed

1 file changed

+21
-5
lines changed

drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2069,19 +2069,35 @@ st_lsm6dsx_report_motion_event(struct st_lsm6dsx_hw *hw)
20692069
static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private)
20702070
{
20712071
struct st_lsm6dsx_hw *hw = private;
2072+
int fifo_len = 0, len;
20722073
bool event;
2073-
int count;
20742074

20752075
event = st_lsm6dsx_report_motion_event(hw);
20762076

20772077
if (!hw->settings->fifo_ops.read_fifo)
20782078
return event ? IRQ_HANDLED : IRQ_NONE;
20792079

2080-
mutex_lock(&hw->fifo_lock);
2081-
count = hw->settings->fifo_ops.read_fifo(hw);
2082-
mutex_unlock(&hw->fifo_lock);
2080+
/*
2081+
* If we are using edge IRQs, new samples can arrive while
2082+
* processing current interrupt since there are no hw
2083+
* guarantees the irq line stays "low" long enough to properly
2084+
* detect the new interrupt. In this case the new sample will
2085+
* be missed.
2086+
* Polling FIFO status register allow us to read new
2087+
* samples even if the interrupt arrives while processing
2088+
* previous data and the timeslot where the line is "low" is
2089+
* too short to be properly detected.
2090+
*/
2091+
do {
2092+
mutex_lock(&hw->fifo_lock);
2093+
len = hw->settings->fifo_ops.read_fifo(hw);
2094+
mutex_unlock(&hw->fifo_lock);
2095+
2096+
if (len > 0)
2097+
fifo_len += len;
2098+
} while (len > 0);
20832099

2084-
return count || event ? IRQ_HANDLED : IRQ_NONE;
2100+
return fifo_len || event ? IRQ_HANDLED : IRQ_NONE;
20852101
}
20862102

20872103
static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw)

0 commit comments

Comments
 (0)