i2c: hisi: Only handle the interrupt of the driver's transfer
authorYicong Yang <yangyicong@hisilicon.com>
Tue, 1 Aug 2023 12:46:25 +0000 (20:46 +0800)
committerWolfram Sang <wsa@kernel.org>
Mon, 14 Aug 2023 13:39:24 +0000 (15:39 +0200)
The controller may be shared with other port, for example the firmware.
Handle the interrupt from other sources will cause crash since some
data are not initialized. So only handle the interrupt of the driver's
transfer and discard others.

Fixes: d62fbdb99a85 ("i2c: add support for HiSilicon I2C controller")
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
Reviewed-by: Andi Shyti <andi.shyti@kernel.org>
Link: https://lore.kernel.org/r/20230801124625.63587-1-yangyicong@huawei.com
Signed-off-by: Wolfram Sang <wsa@kernel.org>
drivers/i2c/busses/i2c-hisi.c

index e067671b3ce2eebed4eab2cb51301aaaa3890529..0980c773cb5b1aa790b8ed39a8132bdccc892ac7 100644 (file)
@@ -330,6 +330,14 @@ static irqreturn_t hisi_i2c_irq(int irq, void *context)
        struct hisi_i2c_controller *ctlr = context;
        u32 int_stat;
 
+       /*
+        * Don't handle the interrupt if cltr->completion is NULL. We may
+        * reach here because the interrupt is spurious or the transfer is
+        * started by another port (e.g. firmware) rather than us.
+        */
+       if (!ctlr->completion)
+               return IRQ_NONE;
+
        int_stat = readl(ctlr->iobase + HISI_I2C_INT_MSTAT);
        hisi_i2c_clear_int(ctlr, int_stat);
        if (!(int_stat & HISI_I2C_INT_ALL))