Commit b97cd6814ec08be56225975a050ee486bfa7c13a
Committed by
Heiko Schocher
1 parent
7e78f7ad7f
Exists in
v2017.01-smarct4x
and in
37 other branches
ppc4xx: Handle i2c stuck on combined xfer
ppc4xx i2c master gets stuck on errors while repeated start is active. Can be easily reproduced by "i2c md" on an unpopulated i2c address. There is not stop condition given, scl remains pulled low. The only way out seems to be doing a stop manually and then a soft reset. Signed-off-by: Dirk Eibach <dirk.eibach@gdsys.cc> Reviewed-by: Stefan Roese <sr@denx.de>
Showing 2 changed files with 23 additions and 0 deletions Side-by-side Diff
arch/powerpc/include/asm/ppc4xx-i2c.h
drivers/i2c/ppc4xx_i2c.c
... | ... | @@ -289,6 +289,27 @@ |
289 | 289 | /* Transfer aborted? */ |
290 | 290 | if (status & IIC_EXTSTS_XFRA) |
291 | 291 | result = IIC_NOK_XFRA; |
292 | + /* Is bus free? | |
293 | + * If error happened during combined xfer | |
294 | + * IIC interface is usually stuck in some strange | |
295 | + * state without a valid stop condition. | |
296 | + * Brute, but working: generate stop, then soft reset. | |
297 | + */ | |
298 | + if ((status & IIC_EXTSTS_BCS_MASK) | |
299 | + != IIC_EXTSTS_BCS_FREE){ | |
300 | + u8 mdcntl = in_8(&i2c->mdcntl); | |
301 | + | |
302 | + /* Generate valid stop condition */ | |
303 | + out_8(&i2c->xtcntlss, IIC_XTCNTLSS_SRST); | |
304 | + out_8(&i2c->directcntl, IIC_DIRCNTL_SCC); | |
305 | + udelay(10); | |
306 | + out_8(&i2c->directcntl, | |
307 | + IIC_DIRCNTL_SCC | IIC_DIRCNTL_SDAC); | |
308 | + out_8(&i2c->xtcntlss, 0); | |
309 | + | |
310 | + ppc4xx_i2c_init(adap, (mdcntl & IIC_MDCNTL_FSM) | |
311 | + ? 400000 : 100000, 0); | |
312 | + } | |
292 | 313 | } else if ( status & IIC_STS_PT) { |
293 | 314 | result = IIC_NOK_TOUT; |
294 | 315 | } |