On Fri, 2024-05-24 at 12:00 +0300, Ramona Gradinariu wrote: > Currently, adis library allows configuration only for edge interrupts, > needed for data ready sampling. > This patch removes the restriction for level interrupts for devices > which have FIFO support. > Furthermore, in case of devices which have FIFO support, > devm_request_threaded_irq is used for interrupt allocation, to avoid > flooding the processor with the FIFO watermark level interrupt, which > is active until enough data has been read from the FIFO. > > Signed-off-by: Ramona Gradinariu <ramona.bolboaca13@xxxxxxxxx> > --- Reviewed-by: Nuno Sa <nuno.sa@xxxxxxxxxx> (much better, IMO, commit message :)) > drivers/iio/imu/adis_trigger.c | 37 ++++++++++++++++++++++++---------- > include/linux/iio/imu/adis.h | 1 + > 2 files changed, 27 insertions(+), 11 deletions(-) > > diff --git a/drivers/iio/imu/adis_trigger.c b/drivers/iio/imu/adis_trigger.c > index f890bf842db8..a8740b043cfe 100644 > --- a/drivers/iio/imu/adis_trigger.c > +++ b/drivers/iio/imu/adis_trigger.c > @@ -34,17 +34,24 @@ static int adis_validate_irq_flag(struct adis *adis) > if (adis->data->unmasked_drdy) > adis->irq_flag |= IRQF_NO_AUTOEN; > /* > - * Typically this devices have data ready either on the rising edge or > - * on the falling edge of the data ready pin. This checks enforces that > - * one of those is set in the drivers... It defaults to > - * IRQF_TRIGGER_RISING for backward compatibility with devices that > - * don't support changing the pin polarity. > + * Typically adis devices without FIFO have data ready either on the > + * rising edge or on the falling edge of the data ready pin. > + * IMU devices with FIFO support have the watermark pin level driven > + * either high or low when the FIFO is filled with the desired number > + * of samples. > + * It defaults to IRQF_TRIGGER_RISING for backward compatibility with > + * devices that don't support changing the pin polarity. > */ > if (direction == IRQF_TRIGGER_NONE) { > adis->irq_flag |= IRQF_TRIGGER_RISING; > return 0; > } else if (direction != IRQF_TRIGGER_RISING && > - direction != IRQF_TRIGGER_FALLING) { > + direction != IRQF_TRIGGER_FALLING && !adis->data->has_fifo) { > + dev_err(&adis->spi->dev, "Invalid IRQ mask: %08lx\n", > + adis->irq_flag); > + return -EINVAL; > + } else if (direction != IRQF_TRIGGER_HIGH && > + direction != IRQF_TRIGGER_LOW && adis->data->has_fifo) { > dev_err(&adis->spi->dev, "Invalid IRQ mask: %08lx\n", > adis->irq_flag); > return -EINVAL; > @@ -77,11 +84,19 @@ int devm_adis_probe_trigger(struct adis *adis, struct iio_dev > *indio_dev) > if (ret) > return ret; > > - ret = devm_request_irq(&adis->spi->dev, adis->spi->irq, > - &iio_trigger_generic_data_rdy_poll, > - adis->irq_flag, > - indio_dev->name, > - adis->trig); > + if (adis->data->has_fifo) > + ret = devm_request_threaded_irq(&adis->spi->dev, adis->spi->irq, > + NULL, > + &iio_trigger_generic_data_rdy_poll > , > + adis->irq_flag | IRQF_ONESHOT, > + indio_dev->name, > + adis->trig); > + else > + ret = devm_request_irq(&adis->spi->dev, adis->spi->irq, > + &iio_trigger_generic_data_rdy_poll, > + adis->irq_flag, > + indio_dev->name, > + adis->trig); > if (ret) > return ret; > > diff --git a/include/linux/iio/imu/adis.h b/include/linux/iio/imu/adis.h > index 8dda3cfa5773..4d4cdbe155b2 100644 > --- a/include/linux/iio/imu/adis.h > +++ b/include/linux/iio/imu/adis.h > @@ -85,6 +85,7 @@ struct adis_data { > bool unmasked_drdy; > > bool has_paging; > + bool has_fifo; > > unsigned int burst_reg_cmd; > unsigned int burst_len;