On 2018-07-10 23:42, Wolfram Sang wrote: > 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@xxxxxxxxxxxxxxxxxxxx> > --- > drivers/i2c/i2c-core-base.c | 11 ++++++++++- > 1 file changed, 10 insertions(+), 1 deletion(-) > > diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c > index 31d16ada6e7d..301285c54603 100644 > --- a/drivers/i2c/i2c-core-base.c > +++ b/drivers/i2c/i2c-core-base.c > @@ -198,7 +198,16 @@ int i2c_generic_scl_recovery(struct i2c_adapter *adap) > > val = !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 */ > Hmmm, should not the ndelay before the loop also be split up in two like this, with one ndelay(... / 2) on either side of the (possible) set_sda. Not that it should matter, since SDA is presumably stuck low. But what if it isn't? I would also change the while (...) to for (i = 0; i < RECOVERY_CLK_CNT * 2; i++) but both these "issues" are perhaps not related to this patch... Either way, Reviewed-by: Peter Rosin <peda@xxxxxxxxxx> Cheers, Peter