iowrite8(val, bus->reg + NPCM_I2CCTL1);
 }
 
+static inline void npcm_i2c_clear_master_status(struct npcm_i2c *bus)
+{
+       u8 val;
+
+       /* Clear NEGACK, STASTR and BER bits */
+       val = NPCM_I2CST_BER | NPCM_I2CST_NEGACK | NPCM_I2CST_STASTR;
+       iowrite8(val, bus->reg + NPCM_I2CST);
+}
+
 #if IS_ENABLED(CONFIG_I2C_SLAVE)
 static void npcm_i2c_slave_int_enable(struct npcm_i2c *bus, bool enable)
 {
        iowrite8(NPCM_I2CCST_BB, bus->reg + NPCM_I2CCST);
        iowrite8(0xFF, bus->reg + NPCM_I2CST);
 
-       /* Clear EOB bit */
-       iowrite8(NPCM_I2CCST3_EO_BUSY, bus->reg + NPCM_I2CCST3);
+       /* Clear and disable EOB */
+       npcm_i2c_eob_int(bus, false);
 
        /* Clear all fifo bits: */
        iowrite8(NPCM_I2CFIF_CTS_CLR_FIFO, bus->reg + NPCM_I2CFIF_CTS);
        }
 #endif
 
+       /* clear status bits for spurious interrupts */
+       npcm_i2c_clear_master_status(bus);
+
        bus->state = I2C_IDLE;
 }
 
        }
 }
 
-static inline void npcm_i2c_clear_master_status(struct npcm_i2c *bus)
-{
-       u8 val;
-
-       /* Clear NEGACK, STASTR and BER bits */
-       val = NPCM_I2CST_BER | NPCM_I2CST_NEGACK | NPCM_I2CST_STASTR;
-       iowrite8(val, bus->reg + NPCM_I2CST);
-}
-
 static void npcm_i2c_master_abort(struct npcm_i2c *bus)
 {
        /* Only current master is allowed to issue a stop condition */
                ret = IRQ_HANDLED;
        } /* SDAST */
 
-       return ret;
+       /*
+        * if irq is not one of the above, make sure EOB is disabled and all
+        * status bits are cleared.
+        */
+       if (ret == IRQ_NONE) {
+               npcm_i2c_eob_int(bus, false);
+               npcm_i2c_clear_master_status(bus);
+       }
+
+       return IRQ_HANDLED;
 }
 
 static int npcm_i2c_reg_slave(struct i2c_client *client)
                npcm_i2c_eob_int(bus, false);
                npcm_i2c_master_stop(bus);
 
+               /* Clear SDA Status bit (by reading dummy byte) */
+               npcm_i2c_rd_byte(bus);
+
                /*
                 * The bus is released from stall only after the SW clears
                 * NEGACK bit. Then a Stop condition is sent.
                npcm_i2c_clear_master_status(bus);
                readx_poll_timeout_atomic(ioread8, bus->reg + NPCM_I2CCST, val,
                                          !(val & NPCM_I2CCST_BUSY), 10, 200);
+               /* verify no status bits are still set after bus is released */
+               npcm_i2c_clear_master_status(bus);
        }
        bus->state = I2C_IDLE;
 
        int              iter = 27;
 
        if ((npcm_i2c_get_SDA(_adap) == 1) && (npcm_i2c_get_SCL(_adap) == 1)) {
-               dev_dbg(bus->dev, "bus%d recovery skipped, bus not stuck",
-                       bus->num);
+               dev_dbg(bus->dev, "bus%d-0x%x recovery skipped, bus not stuck",
+                       bus->num, bus->dest_addr);
                npcm_i2c_reset(bus);
-               return status;
+               return 0;
        }
 
        npcm_i2c_int_enable(bus, false);
            bus_freq_hz < I2C_FREQ_MIN_HZ || bus_freq_hz > I2C_FREQ_MAX_HZ)
                return -EINVAL;
 
+       npcm_i2c_int_enable(bus, false);
        npcm_i2c_disable(bus);
 
        /* Configure FIFO mode : */
        val = (val | NPCM_I2CCTL1_NMINTE) & ~NPCM_I2CCTL1_RWS;
        iowrite8(val, bus->reg + NPCM_I2CCTL1);
 
-       npcm_i2c_int_enable(bus, true);
-
        npcm_i2c_reset(bus);
 
+       /* check HW is OK: SDA and SCL should be high at this point. */
+       if ((npcm_i2c_get_SDA(&bus->adap) == 0) || (npcm_i2c_get_SCL(&bus->adap) == 0)) {
+               dev_err(bus->dev, "I2C%d init fail: lines are low\n", bus->num);
+               dev_err(bus->dev, "SDA=%d SCL=%d\n", npcm_i2c_get_SDA(&bus->adap),
+                       npcm_i2c_get_SCL(&bus->adap));
+               return -ENXIO;
+       }
+
+       npcm_i2c_int_enable(bus, true);
        return 0;
 }
 
 #if IS_ENABLED(CONFIG_I2C_SLAVE)
        if (bus->slave) {
                bus->master_or_slave = I2C_SLAVE;
-               return npcm_i2c_int_slave_handler(bus);
+               if (npcm_i2c_int_slave_handler(bus))
+                       return IRQ_HANDLED;
        }
 #endif
-       return IRQ_NONE;
+       /* clear status bits for spurious interrupts */
+       npcm_i2c_clear_master_status(bus);
+
+       return IRQ_HANDLED;
 }
 
 static bool npcm_i2c_master_start_xmit(struct npcm_i2c *bus,
        u8 *write_data, *read_data;
        u8 slave_addr;
        unsigned long timeout;
-       int ret = 0;
        bool read_block = false;
        bool read_PEC = false;
        u8 bus_busy;
        bus->read_block_use = read_block;
 
        reinit_completion(&bus->cmd_complete);
-       if (!npcm_i2c_master_start_xmit(bus, slave_addr, nwrite, nread,
-                                       write_data, read_data, read_PEC,
-                                       read_block))
-               ret = -EBUSY;
 
-       if (ret != -EBUSY) {
+       npcm_i2c_int_enable(bus, true);
+
+       if (npcm_i2c_master_start_xmit(bus, slave_addr, nwrite, nread,
+                                      write_data, read_data, read_PEC,
+                                      read_block)) {
                time_left = wait_for_completion_timeout(&bus->cmd_complete,
                                                        timeout);
 
                        }
                }
        }
-       ret = bus->cmd_err;
 
        /* if there was BER, check if need to recover the bus: */
        if (bus->cmd_err == -EAGAIN)
-               ret = i2c_recover_bus(adap);
+               bus->cmd_err = i2c_recover_bus(adap);
 
        /*
         * After any type of error, check if LAST bit is still set,
         * due to a HW issue.
         * It cannot be cleared without resetting the module.
         */
-       if (bus->cmd_err &&
-           (NPCM_I2CRXF_CTL_LAST_PEC & ioread8(bus->reg + NPCM_I2CRXF_CTL)))
+       else if (bus->cmd_err &&
+                (NPCM_I2CRXF_CTL_LAST_PEC & ioread8(bus->reg + NPCM_I2CRXF_CTL)))
                npcm_i2c_reset(bus);
 
+       /* after any xfer, successful or not, stall and EOB must be disabled */
+       npcm_i2c_stall_after_start(bus, false);
+       npcm_i2c_eob_int(bus, false);
+
 #if IS_ENABLED(CONFIG_I2C_SLAVE)
        /* reenable slave if it was enabled */
        if (bus->slave)
                iowrite8((bus->slave->addr & 0x7F) | NPCM_I2CADDR_SAEN,
                         bus->reg + NPCM_I2CADDR1);
+#else
+       npcm_i2c_int_enable(bus, false);
 #endif
        return bus->cmd_err;
 }