Skip to content

Commit 0fc3562

Browse files
nxpfranklijic23
authored andcommitted
iio: imx8qxp-adc: fix irq flood when call imx8qxp_adc_read_raw()
irq flood happen when run cat /sys/bus/iio/devices/iio:device0/in_voltage1_raw imx8qxp_adc_read_raw() { ... enable irq /* adc start */ writel(1, adc->regs + IMX8QXP_ADR_ADC_SWTRIG); ^^^^ trigger irq flood. wait_for_completion_interruptible_timeout(); readl(adc->regs + IMX8QXP_ADR_ADC_RESFIFO); ^^^^ clear irq here. ... } There is only FIFO watermark interrupt at this ADC controller. IRQ line will be assert until software read data from FIFO. So IRQ flood happen during wait_for_completion_interruptible_timeout(). Move FIFO read into irq handle to avoid irq flood. Fixes: 1e23dca ("iio: imx8qxp-adc: Add driver support for NXP IMX8QXP ADC") Cc: [email protected] Signed-off-by: Frank Li <[email protected]> Reviewed-by: Cai Huoqing <[email protected]> Reviewed-by: Haibo Chen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Cc: <[email protected]> Signed-off-by: Jonathan Cameron <[email protected]>
1 parent 6794ed0 commit 0fc3562

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

drivers/iio/adc/imx8qxp-adc.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@
8686

8787
#define IMX8QXP_ADC_TIMEOUT msecs_to_jiffies(100)
8888

89+
#define IMX8QXP_ADC_MAX_FIFO_SIZE 16
90+
8991
struct imx8qxp_adc {
9092
struct device *dev;
9193
void __iomem *regs;
@@ -95,6 +97,7 @@ struct imx8qxp_adc {
9597
/* Serialise ADC channel reads */
9698
struct mutex lock;
9799
struct completion completion;
100+
u32 fifo[IMX8QXP_ADC_MAX_FIFO_SIZE];
98101
};
99102

100103
#define IMX8QXP_ADC_CHAN(_idx) { \
@@ -238,8 +241,7 @@ static int imx8qxp_adc_read_raw(struct iio_dev *indio_dev,
238241
return ret;
239242
}
240243

241-
*val = FIELD_GET(IMX8QXP_ADC_RESFIFO_VAL_MASK,
242-
readl(adc->regs + IMX8QXP_ADR_ADC_RESFIFO));
244+
*val = adc->fifo[0];
243245

244246
mutex_unlock(&adc->lock);
245247
return IIO_VAL_INT;
@@ -265,10 +267,15 @@ static irqreturn_t imx8qxp_adc_isr(int irq, void *dev_id)
265267
{
266268
struct imx8qxp_adc *adc = dev_id;
267269
u32 fifo_count;
270+
int i;
268271

269272
fifo_count = FIELD_GET(IMX8QXP_ADC_FCTRL_FCOUNT_MASK,
270273
readl(adc->regs + IMX8QXP_ADR_ADC_FCTRL));
271274

275+
for (i = 0; i < fifo_count; i++)
276+
adc->fifo[i] = FIELD_GET(IMX8QXP_ADC_RESFIFO_VAL_MASK,
277+
readl_relaxed(adc->regs + IMX8QXP_ADR_ADC_RESFIFO));
278+
272279
if (fifo_count)
273280
complete(&adc->completion);
274281

0 commit comments

Comments
 (0)