i2c: recovery: if possible send STOP with recovery pulses

I2C clients may misunderstand recovery pulses if they can't read SDA to
bail out early. In the worst case, as a write operation. To avoid that
and if we can write SDA, try to send STOP to avoid the
misinterpretation.

Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Reviewed-by: Peter Rosin <peda@axentia.se>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Cc: stable@kernel.org
This commit is contained in:
Wolfram Sang 2018-07-10 23:42:15 +02:00 committed by Wolfram Sang
parent 54836e2d03
commit abe41184ab

View File

@ -198,7 +198,16 @@ int i2c_generic_scl_recovery(struct i2c_adapter *adap)
val = !val; val = !val;
bri->set_scl(adap, val); bri->set_scl(adap, val);
ndelay(RECOVERY_NDELAY);
/*
* If we can set SDA, we will always create STOP here to ensure
* the additional pulses will do no harm. This is achieved by
* letting SDA follow SCL half a cycle later.
*/
ndelay(RECOVERY_NDELAY / 2);
if (bri->set_sda)
bri->set_sda(adap, val);
ndelay(RECOVERY_NDELAY / 2);
} }
/* check if recovery actually succeeded */ /* check if recovery actually succeeded */