i2c:i2c-bfin-twi: Read and write the FIFO in loop.
PATCH 1/1 i2c:i2c-bfin-twi: Read and write the FIFO in loop.
From: Sonic Zhang <[email protected]>
TWI transfer interrupts may be lost when system is heavily handling other interrupts, while current transfer handler depends on each accurate interrupt and misses some data in this case. Because there are 2 2-byte FIFOs in blackfin TWI controller, the occurrence of the data loss can be reduced by reading till the RX FIFO is empty and writing till the TX FIFO is full.
--- drivers/i2c/busses/i2c-bfin-twi.c | 47 ++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 20 deletions(-)
drivers/i2c/busses/i2c-bfin-twi.c +27 -20
@@ -39,33 +39,40 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface,unsigned short mast_stat =read_MASTER_STAT (iface);if (twi_int_status &XMTSERV ) { +if (iface->writeNum <=0 ) { +/* start receive immediately after complete sending in +* combine mode. +*/ +if (iface->cur_mode ==TWI_I2C_MODE_COMBINED ) +write_MASTER_CTL (iface, +read_MASTER_CTL (iface) |MDIR ); +else if (iface->manual_stop) +write_MASTER_CTL (iface, +read_MASTER_CTL (iface) |STOP ); +else if (iface->cur_mode ==TWI_I2C_MODE_REPEAT && + iface->cur_msg +1 < iface->msg_num) { +if (iface->pmsg[iface->cur_msg +1 ].flags & +I2C_M_RD ) +write_MASTER_CTL (iface, +read_MASTER_CTL (iface) | +MDIR ); +else +write_MASTER_CTL (iface, +read_MASTER_CTL (iface) & + ~MDIR ); + } + }/* Transmit next data */ -if (iface->writeNum >0 ) { +while (iface->writeNum >0 && + (read_FIFO_STAT (iface) &XMTSTAT ) !=XMT_FULL ) {SSYNC ();write_XMT_DATA8 (iface, *(iface->transPtr++)); iface->writeNum--; } -/* start receive immediately after complete sending in -* combine mode. -*/ -else if (iface->cur_mode ==TWI_I2C_MODE_COMBINED ) -write_MASTER_CTL (iface, -read_MASTER_CTL (iface) |MDIR ); -else if (iface->manual_stop) -write_MASTER_CTL (iface, -read_MASTER_CTL (iface) |STOP ); -else if (iface->cur_mode ==TWI_I2C_MODE_REPEAT && - iface->cur_msg +1 < iface->msg_num) { -if (iface->pmsg[iface->cur_msg +1 ].flags &I2C_M_RD ) -write_MASTER_CTL (iface, -read_MASTER_CTL (iface) |MDIR ); -else -write_MASTER_CTL (iface, -read_MASTER_CTL (iface) & ~MDIR ); - } }if (twi_int_status &RCVSERV ) { -if (iface->readNum >0 ) { +while (iface->readNum >0 && + (read_FIFO_STAT (iface) &RCVSTAT )) {/* Receive next data */ *(iface->transPtr) =read_RCV_DATA8 (iface);if (iface->cur_mode ==TWI_I2C_MODE_COMBINED ) {
Signature · 1 line
1.8.2.3
A message that is not in the archive (sent off-list or not yet received): 1369737669-14226-1-git-send-email-sonic.adi-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Wolfram Sang
AppliedQuoted 11 lines · Sonic Zhang
From: Sonic Zhang <[email protected]>
Reported-by Bob Maris <[email protected]>TWI transfer interrupts may be lost when system is heavily handling other interrupts, while current transfer handler depends on each accurate interrupt and misses some data in this case. Because there are 2 2-byte FIFOs in blackfin TWI controller, the occurrence of the data loss can be reduced by reading till the RX FIFO is empty and writing till the TX FIFO is full.
Signed-off-by Sonic Zhang <[email protected]>
Applied to for-next, thanks!