From 9656eeebf3f1dd05376c4c923797369746d9a618 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 16 Nov 2015 14:42:03 +0100 Subject: [PATCH] i2c: Revert "i2c: xiic: Do not reset controller before every transfer" Commit d701667bb331 ("i2c: xiic: Do not reset controller before every transfer") removed the reinitialization of the controller before the start of each transfer. Apparently this change is not safe to make and the commit results in random I2C bus failures. An easy way to trigger the issue is to run i2cdetect. Without the patch applied: 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- UU UU -- UU 3c -- -- UU 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- -- With the patch applied every other or so invocation: 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10: 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20: 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30: -- -- -- -- -- -- -- -- UU UU -- UU 3c -- -- UU 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- -- So revert the commit for now. Fixes: d701667bb331 ("i2c: xiic: Do not reset controller before every transfer") Signed-off-by: Lars-Peter Clausen Acked-by: Shubhrajyoti Datta Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-xiic.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c index e23a7b068c60..705cf69ccf42 100644 --- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c @@ -662,6 +662,9 @@ static void __xiic_start_xfer(struct xiic_i2c *i2c) static void xiic_start_xfer(struct xiic_i2c *i2c) { + spin_lock(&i2c->lock); + xiic_reinit(i2c); + spin_unlock(&i2c->lock); __xiic_start_xfer(i2c); } -- 2.30.2