Skip to content

Commit 12d4d9e

Browse files
Raviteja Narayanamwsakernel
authored andcommitted
i2c: cadence: Clear HOLD bit at correct time in Rx path
There are few issues on Zynq SOC observed in the stress tests causing timeout errors. Even though all the data is received, timeout error is thrown. This is due to an IP bug in which the COMP bit in ISR is not set at end of transfer and completion interrupt is not generated. This bug is seen on Zynq platforms when the following condition occurs: Master read & HOLD bit set & Transfer size register reaches '0'. One workaround is to clear the HOLD bit before the transfer size register reaches '0'. The current implementation checks for this at the start of the loop and also only for less than FIFO DEPTH case (ignoring the equal to case). So clear the HOLD bit when the data yet to receive is less than or equal to the FIFO DEPTH. This avoids the IP bug condition. Signed-off-by: Raviteja Narayanam <[email protected]> Acked-by: Michal Simek <[email protected]> Signed-off-by: Wolfram Sang <[email protected]>
1 parent 0db9254 commit 12d4d9e

File tree

1 file changed

+10
-9
lines changed

1 file changed

+10
-9
lines changed

drivers/i2c/busses/i2c-cadence.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -421,20 +421,21 @@ static irqreturn_t cdns_i2c_master_isr(void *ptr)
421421
/* Read data if receive data valid is set */
422422
while (cdns_i2c_readreg(CDNS_I2C_SR_OFFSET) &
423423
CDNS_I2C_SR_RXDV) {
424-
/*
425-
* Clear hold bit that was set for FIFO control if
426-
* RX data left is less than FIFO depth, unless
427-
* repeated start is selected.
428-
*/
429-
if ((id->recv_count < CDNS_I2C_FIFO_DEPTH) &&
430-
!id->bus_hold_flag)
431-
cdns_i2c_clear_bus_hold(id);
432-
433424
if (id->recv_count > 0) {
434425
*(id->p_recv_buf)++ =
435426
cdns_i2c_readreg(CDNS_I2C_DATA_OFFSET);
436427
id->recv_count--;
437428
id->curr_recv_count--;
429+
430+
/*
431+
* Clear hold bit that was set for FIFO control
432+
* if RX data left is less than or equal to
433+
* FIFO DEPTH unless repeated start is selected
434+
*/
435+
if (id->recv_count <= CDNS_I2C_FIFO_DEPTH &&
436+
!id->bus_hold_flag)
437+
cdns_i2c_clear_bus_hold(id);
438+
438439
} else {
439440
dev_err(id->adap.dev.parent,
440441
"xfer_size reg rollover. xfer aborted!\n");

0 commit comments

Comments
 (0)