Commit 28a377c79af918fc40c70553216571314c5f42a4

Authored by Sonic Zhang
Committed by Wolfram Sang
1 parent 2ee74eb95c

i2c:i2c-bfin-twi: TWI fails to restart next transfer in high system load.

Current driver was developed based on BF537 0.2 HRM. In high system load, BUFRDERR error
interrupt may be raised if XMTSERV interrupt of last TX byte is not served in time
(set RSTART bit), which breaks restart tranfer as expected.

"Buffer Read Error (BUFRDERR)" description in Blackfin HRM only applys to BF537
rev. < 0.3. In later rev. and later announced Blackfin chips, such as BF527 and
BF548, a new TWI master feature "Clock Stretching" is added into the TWI controller,
BUFRDERR interrupt is not triggered after TX FIFO is empty.

This patch sets RSTART bit at the beginning of the first transfer. The SCL and SDA
is hold till XMTSERV interrupt of last TX byte is served. Restart transfer is not broken
in high system load.

Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>

[wsa: fixed spaces around operators]

Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>

Showing 1 changed file with 14 additions and 11 deletions Side-by-side Diff

drivers/i2c/busses/i2c-bfin-twi.c
... ... @@ -99,7 +99,7 @@
99 99 */
100 100 else if (iface->cur_mode == TWI_I2C_MODE_COMBINED)
101 101 write_MASTER_CTL(iface,
102   - read_MASTER_CTL(iface) | MDIR | RSTART);
  102 + read_MASTER_CTL(iface) | MDIR);
103 103 else if (iface->manual_stop)
104 104 write_MASTER_CTL(iface,
105 105 read_MASTER_CTL(iface) | STOP);
106 106  
... ... @@ -107,10 +107,10 @@
107 107 iface->cur_msg + 1 < iface->msg_num) {
108 108 if (iface->pmsg[iface->cur_msg + 1].flags & I2C_M_RD)
109 109 write_MASTER_CTL(iface,
110   - read_MASTER_CTL(iface) | RSTART | MDIR);
  110 + read_MASTER_CTL(iface) | MDIR);
111 111 else
112 112 write_MASTER_CTL(iface,
113   - (read_MASTER_CTL(iface) | RSTART) & ~MDIR);
  113 + read_MASTER_CTL(iface) & ~MDIR);
114 114 }
115 115 }
116 116 if (twi_int_status & RCVSERV) {
117 117  
... ... @@ -144,10 +144,10 @@
144 144 iface->cur_msg + 1 < iface->msg_num) {
145 145 if (iface->pmsg[iface->cur_msg + 1].flags & I2C_M_RD)
146 146 write_MASTER_CTL(iface,
147   - read_MASTER_CTL(iface) | RSTART | MDIR);
  147 + read_MASTER_CTL(iface) | MDIR);
148 148 else
149 149 write_MASTER_CTL(iface,
150   - (read_MASTER_CTL(iface) | RSTART) & ~MDIR);
  150 + read_MASTER_CTL(iface) & ~MDIR);
151 151 }
152 152 }
153 153 }
... ... @@ -230,7 +230,7 @@
230 230 write_MASTER_CTL(iface,
231 231 read_MASTER_CTL(iface) & ~RSTART);
232 232 } else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&
233   - iface->cur_msg+1 < iface->msg_num) {
  233 + iface->cur_msg + 1 < iface->msg_num) {
234 234 iface->cur_msg++;
235 235 iface->transPtr = iface->pmsg[iface->cur_msg].buf;
236 236 iface->writeNum = iface->readNum =
... ... @@ -262,9 +262,10 @@
262 262 (0xff << 6)));
263 263 iface->manual_stop = 1;
264 264 }
265   - /* remove restart bit and enable master receive */
266   - write_MASTER_CTL(iface,
267   - read_MASTER_CTL(iface) & ~RSTART);
  265 + /* remove restart bit before last message */
  266 + if (iface->cur_msg + 1 == iface->msg_num)
  267 + write_MASTER_CTL(iface,
  268 + read_MASTER_CTL(iface) & ~RSTART);
268 269 } else {
269 270 iface->result = 1;
270 271 write_INT_MASK(iface, 0);
... ... @@ -321,7 +322,8 @@
321 322 return -EINVAL;
322 323 }
323 324  
324   - iface->cur_mode = TWI_I2C_MODE_REPEAT;
  325 + if (iface->msg_num > 1)
  326 + iface->cur_mode = TWI_I2C_MODE_REPEAT;
325 327 iface->manual_stop = 0;
326 328 iface->transPtr = pmsg->buf;
327 329 iface->writeNum = iface->readNum = pmsg->len;
... ... @@ -366,6 +368,7 @@
366 368  
367 369 /* Master enable */
368 370 write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN |
  371 + (iface->msg_num > 1 ? RSTART : 0) |
369 372 ((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) |
370 373 ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0));
371 374 SSYNC();
... ... @@ -530,7 +533,7 @@
530 533 else
531 534 write_MASTER_CTL(iface, 0x1 << 6);
532 535 /* Master enable */
533   - write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN |
  536 + write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN | RSTART |
534 537 ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0));
535 538 break;
536 539 default: