diff options
Diffstat (limited to 'drivers/i2c/i2c-core-base.c')
| -rw-r--r-- | drivers/i2c/i2c-core-base.c | 13 | 
1 files changed, 10 insertions, 3 deletions
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index 9f8dcd3f8385..35b209797d7b 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -186,10 +186,11 @@ int i2c_generic_scl_recovery(struct i2c_adapter *adap)  	 * If we can set SDA, we will always create a STOP to ensure additional  	 * pulses will do no harm. This is achieved by letting SDA follow SCL  	 * half a cycle later. Check the 'incomplete_write_byte' fault injector -	 * for details. +	 * for details. Note that we must honour tsu:sto, 4us, but lets use 5us +	 * here for simplicity.  	 */  	bri->set_scl(adap, scl); -	ndelay(RECOVERY_NDELAY / 2); +	ndelay(RECOVERY_NDELAY);  	if (bri->set_sda)  		bri->set_sda(adap, scl);  	ndelay(RECOVERY_NDELAY / 2); @@ -211,7 +212,13 @@ int i2c_generic_scl_recovery(struct i2c_adapter *adap)  		scl = !scl;  		bri->set_scl(adap, scl);  		/* Creating STOP again, see above */ -		ndelay(RECOVERY_NDELAY / 2); +		if (scl)  { +			/* Honour minimum tsu:sto */ +			ndelay(RECOVERY_NDELAY); +		} else { +			/* Honour minimum tf and thd:dat */ +			ndelay(RECOVERY_NDELAY / 2); +		}  		if (bri->set_sda)  			bri->set_sda(adap, scl);  		ndelay(RECOVERY_NDELAY / 2);  | 
