Several functions in this file are trying to use regmap_read() to initialize the specific variable, however, if regmap_read() fails, the variable could be uninitialized but used directly, which is potentially unsafe. The return value of regmap_read() should be checked and handled. Signed-off-by: Yizhuo <yzhai003@xxxxxxx> --- drivers/iio/adc/bcm_iproc_adc.c | 45 ++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/drivers/iio/adc/bcm_iproc_adc.c b/drivers/iio/adc/bcm_iproc_adc.c index 646ebdc0a8b4..6df19ceb5ff2 100644 --- a/drivers/iio/adc/bcm_iproc_adc.c +++ b/drivers/iio/adc/bcm_iproc_adc.c @@ -137,6 +137,7 @@ static irqreturn_t iproc_adc_interrupt_thread(int irq, void *data) u32 channel_intr_status; u32 intr_status; u32 intr_mask; + int ret; struct iio_dev *indio_dev = data; struct iproc_adc_priv *adc_priv = iio_priv(indio_dev); @@ -145,8 +146,19 @@ static irqreturn_t iproc_adc_interrupt_thread(int irq, void *data) * Make sure this interrupt is intended for us. * Handle only ADC channel specific interrupts. */ - regmap_read(adc_priv->regmap, IPROC_INTERRUPT_STATUS, &intr_status); - regmap_read(adc_priv->regmap, IPROC_INTERRUPT_MASK, &intr_mask); + ret = regmap_read(adc_priv->regmap, + IPROC_INTERRUPT_STATUS, &intr_status); + if (ret) { + dev_err(&indio_dev->dev, "Fail to read IPROC_INTERRUPT_STATUS.\n"); + return ret; + } + + ret = regmap_read(adc_priv->regmap, IPROC_INTERRUPT_MASK, &intr_mask); + if (ret) { + dev_err(&indio_dev->dev, "Fail to read IPROC_INTERRUPT_MASK.\n"); + return ret; + } + intr_status = intr_status & intr_mask; channel_intr_status = (intr_status & IPROC_ADC_INTR_MASK) >> IPROC_ADC_INTR; @@ -162,6 +174,7 @@ static irqreturn_t iproc_adc_interrupt_handler(int irq, void *data) struct iproc_adc_priv *adc_priv; struct iio_dev *indio_dev = data; unsigned int valid_entries; + int ret; u32 intr_status; u32 intr_channels; u32 channel_status; @@ -169,23 +182,37 @@ static irqreturn_t iproc_adc_interrupt_handler(int irq, void *data) adc_priv = iio_priv(indio_dev); - regmap_read(adc_priv->regmap, IPROC_INTERRUPT_STATUS, &intr_status); + ret = regmap_read(adc_priv->regmap, + IPROC_INTERRUPT_STATUS, &intr_status); + if (ret) { + dev_err(&indio_dev->dev, "Fail to read IPROC_INTERRUPT_STATUS.\n"); + return ret; + } + dev_dbg(&indio_dev->dev, "iproc_adc_interrupt_handler(),INTRPT_STS:%x\n", intr_status); intr_channels = (intr_status & IPROC_ADC_INTR_MASK) >> IPROC_ADC_INTR; if (intr_channels) { - regmap_read(adc_priv->regmap, + ret = regmap_read(adc_priv->regmap, IPROC_ADC_CHANNEL_INTERRUPT_STATUS + IPROC_ADC_CHANNEL_OFFSET * adc_priv->chan_id, &ch_intr_status); + if (ret) { + dev_err(&indio_dev->dev, "Fail to read the register.\n"); + return ret; + } if (ch_intr_status & IPROC_ADC_CHANNEL_WTRMRK_INTR_MASK) { - regmap_read(adc_priv->regmap, + ret = regmap_read(adc_priv->regmap, IPROC_ADC_CHANNEL_STATUS + IPROC_ADC_CHANNEL_OFFSET * adc_priv->chan_id, &channel_status); + if (ret) { + dev_err(&indio_dev->dev, "Fail to read the register.\n"); + return ret; + } valid_entries = ((channel_status & IPROC_ADC_CHANNEL_VALID_ENTERIES_MASK) >> @@ -230,6 +257,7 @@ static int iproc_adc_do_read(struct iio_dev *indio_dev, u32 mask; u32 val_check; int failed_cnt = 0; + int ret; struct iproc_adc_priv *adc_priv = iio_priv(indio_dev); mutex_lock(&adc_priv->mutex); @@ -284,7 +312,12 @@ static int iproc_adc_do_read(struct iio_dev *indio_dev, * Testing has shown that this may loop a few time, but we have never * hit the full count. */ - regmap_read(adc_priv->regmap, IPROC_INTERRUPT_MASK, &val_check); + ret = regmap_read(adc_priv->regmap, IPROC_INTERRUPT_MASK, &val_check); + if (ret) { + dev_err(&indio_dev->dev, "Fail to read IPROC_INTERRUPT_MASK.\n"); + return ret; + } + while (val_check != val) { failed_cnt++; -- 2.17.1