diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c index 75d80161931f..a6103c303b08 100644 --- a/drivers/i2c/busses/i2c-cadence.c +++ b/drivers/i2c/busses/i2c-cadence.c @@ -246,6 +246,20 @@ static irqreturn_t cdns_i2c_isr(int irq, void *ptr) !id->bus_hold_flag) cdns_i2c_clear_bus_hold(id); + if (id->recv_count == 0) + { + unsigned int st = cdns_i2c_readreg(CDNS_I2C_SR_OFFSET); + pr_notice("%s: buffer overrunning !!!- transfer-size=%d ctrl=%#x status=%#x%s int-status=%#x\n", + __func__, + cdns_i2c_readreg(CDNS_I2C_XFER_SIZE_OFFSET), + cdns_i2c_readreg(CDNS_I2C_CR_OFFSET), + st, st & BIT(7) ? "=>Overflow<=" : "", + cdns_i2c_readreg(CDNS_I2C_ISR_OFFSET) + ); + pr_notice("%s:Aborting transfer...\n", __func__); + cdns_i2c_writereg(0, CDNS_I2C_XFER_SIZE_OFFSET); + break; + } *(id->p_recv_buf)++ = cdns_i2c_readreg(CDNS_I2C_DATA_OFFSET); id->recv_count--; @@ -274,11 +288,15 @@ static irqreturn_t cdns_i2c_isr(int irq, void *ptr) */ if (((int)(id->recv_count) - CDNS_I2C_FIFO_DEPTH) > CDNS_I2C_TRANSFER_SIZE) { + pr_info("%s:cdns_i2c_writereg(%d, CDNS_I2C_XFER_SIZE_OFFSET) #1\n", + __func__, CDNS_I2C_TRANSFER_SIZE); cdns_i2c_writereg(CDNS_I2C_TRANSFER_SIZE, CDNS_I2C_XFER_SIZE_OFFSET); id->curr_recv_count = CDNS_I2C_TRANSFER_SIZE + CDNS_I2C_FIFO_DEPTH; } else { + pr_info("%s:cdns_i2c_writereg(%d, CDNS_I2C_XFER_SIZE_OFFSET) #2\n", + __func__, id->recv_count - CDNS_I2C_FIFO_DEPTH); cdns_i2c_writereg(id->recv_count - CDNS_I2C_FIFO_DEPTH, CDNS_I2C_XFER_SIZE_OFFSET); @@ -292,10 +310,14 @@ static irqreturn_t cdns_i2c_isr(int irq, void *ptr) CDNS_I2C_ADDR_OFFSET); if (id->recv_count > CDNS_I2C_TRANSFER_SIZE) { + pr_info("%s:cdns_i2c_writereg(%d, CDNS_I2C_XFER_SIZE_OFFSET) #3\n", + __func__, CDNS_I2C_TRANSFER_SIZE); cdns_i2c_writereg(CDNS_I2C_TRANSFER_SIZE, CDNS_I2C_XFER_SIZE_OFFSET); id->curr_recv_count = CDNS_I2C_TRANSFER_SIZE; } else { + pr_info("%s:cdns_i2c_writereg(%d, CDNS_I2C_XFER_SIZE_OFFSET) #4\n", + __func__, id->recv_count); cdns_i2c_writereg(id->recv_count, CDNS_I2C_XFER_SIZE_OFFSET); id->curr_recv_count = id->recv_count; @@ -398,10 +420,14 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id) * it is more. Enable the interrupts. */ if (id->recv_count > CDNS_I2C_TRANSFER_SIZE) { + pr_info("%s:cdns_i2c_writereg(%d, CDNS_I2C_XFER_SIZE_OFFSET) #5\n", + __func__, CDNS_I2C_XFER_SIZE_OFFSET); cdns_i2c_writereg(CDNS_I2C_TRANSFER_SIZE, CDNS_I2C_XFER_SIZE_OFFSET); id->curr_recv_count = CDNS_I2C_TRANSFER_SIZE; } else { + pr_info("%s:cdns_i2c_writereg(%d, CDNS_I2C_XFER_SIZE_OFFSET) #6\n", + __func__, id->recv_count); cdns_i2c_writereg(id->recv_count, CDNS_I2C_XFER_SIZE_OFFSET); } @@ -499,6 +525,8 @@ static void cdns_i2c_master_reset(struct i2c_adapter *adap) regval |= CDNS_I2C_CR_CLR_FIFO; cdns_i2c_writereg(regval, CDNS_I2C_CR_OFFSET); /* Update the transfercount register to zero */ + pr_info("%s:cdns_i2c_writereg(%d, CDNS_I2C_XFER_SIZE_OFFSET) #4\n", + __func__, 0); cdns_i2c_writereg(0, CDNS_I2C_XFER_SIZE_OFFSET); /* Clear the interupt status register */ regval = cdns_i2c_readreg(CDNS_I2C_ISR_OFFSET); @@ -530,6 +558,7 @@ static int cdns_i2c_process_msg(struct cdns_i2c *id, struct i2c_msg *msg, CDNS_I2C_CR_OFFSET); } + pr_info("%s: %s len=%d #8\n", __func__, msg->flags & I2C_M_RD ? "Rd" : "Wr", msg->len); /* Check for the R/W flag on each msg */ if (msg->flags & I2C_M_RD) cdns_i2c_mrecv(id); @@ -629,6 +658,7 @@ static int cdns_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, goto out; } ret = -EIO; + pr_info("%s: id->err_status=%#x\n", __func__, id->err_status); goto out; } }