Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

authored by

Wolfram Sang and committed by
Wolfram Sang
abe41184 54836e2d

+10 -1
+10 -1
drivers/i2c/i2c-core-base.c
··· 198 198 199 199 val = !val; 200 200 bri->set_scl(adap, val); 201 - ndelay(RECOVERY_NDELAY); 201 + 202 + /* 203 + * If we can set SDA, we will always create STOP here to ensure 204 + * the additional pulses will do no harm. This is achieved by 205 + * letting SDA follow SCL half a cycle later. 206 + */ 207 + ndelay(RECOVERY_NDELAY / 2); 208 + if (bri->set_sda) 209 + bri->set_sda(adap, val); 210 + ndelay(RECOVERY_NDELAY / 2); 202 211 } 203 212 204 213 /* check if recovery actually succeeded */