int iobase;
        u32 reg_shift;
        u32 reg_io_width;
+       unsigned long flags;
        wait_queue_head_t wait;
        struct i2c_adapter adap;
        struct i2c_msg *msg;
 #define TYPE_GRLIB             1
 #define TYPE_SIFIVE_REV0       2
 
+#define OCORES_FLAG_BROKEN_IRQ BIT(1) /* Broken IRQ for FU540-C000 SoC */
+
 static void oc_setreg_8(struct ocores_i2c *i2c, int reg, u8 value)
 {
        iowrite8(value, i2c->base + (reg << i2c->reg_shift));
        struct ocores_i2c *i2c = dev_id;
        u8 stat = oc_getreg(i2c, OCI2C_STATUS);
 
-       if (!(stat & OCI2C_STAT_IF))
+       if (i2c->flags & OCORES_FLAG_BROKEN_IRQ) {
+               if ((stat & OCI2C_STAT_IF) && !(stat & OCI2C_STAT_BUSY))
+                       return IRQ_NONE;
+       } else if (!(stat & OCI2C_STAT_IF)) {
                return IRQ_NONE;
-
+       }
        ocores_process(i2c, stat);
 
        return IRQ_HANDLED;
                ret = ocores_isr(-1, i2c);
                if (ret == IRQ_NONE)
                        break; /* all messages have been transferred */
+               else {
+                       if (i2c->flags & OCORES_FLAG_BROKEN_IRQ)
+                               if (i2c->state == STATE_DONE)
+                                       break;
+               }
        }
 }
 
 {
        struct ocores_i2c *i2c;
        struct ocores_i2c_platform_data *pdata;
+       const struct of_device_id *match;
        struct resource *res;
        int irq;
        int ret;
        irq = platform_get_irq(pdev, 0);
        if (irq == -ENXIO) {
                ocores_algorithm.master_xfer = ocores_xfer_polling;
+
+               /*
+                * Set in OCORES_FLAG_BROKEN_IRQ to enable workaround for
+                * FU540-C000 SoC in polling mode.
+                */
+               match = of_match_node(ocores_i2c_match, pdev->dev.of_node);
+               if (match && (long)match->data == TYPE_SIFIVE_REV0)
+                       i2c->flags |= OCORES_FLAG_BROKEN_IRQ;
        } else {
                if (irq < 0)
                        return irq;