On 19.09.2019 18:06, kbouhara wrote: > > On 9/11/19 11:58 AM, Codrin Ciubotariu wrote: >> After a transfer timeout, some faulty I2C slave devices might hold down >> the SCL or the SDA pins. We can generate a bus clear command, hoping that >> the slave might release the pins. >> >> Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@xxxxxxxxxxxxx> >> --- >> drivers/i2c/busses/i2c-at91-master.c | 20 ++++++++++++++++++++ >> drivers/i2c/busses/i2c-at91.h | 6 +++++- >> 2 files changed, 25 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/i2c/busses/i2c-at91-master.c >> b/drivers/i2c/busses/i2c-at91-master.c >> index a3fcc35ffd3b..5f544a16db96 100644 >> --- a/drivers/i2c/busses/i2c-at91-master.c >> +++ b/drivers/i2c/busses/i2c-at91-master.c >> @@ -599,6 +599,26 @@ static int at91_do_twi_transfer(struct >> at91_twi_dev *dev) >> at91_twi_write(dev, AT91_TWI_CR, >> AT91_TWI_THRCLR | AT91_TWI_LOCKCLR); >> } >> + >> + /* >> + * After timeout, some faulty I2C slave devices might hold >> SCL/SDA down; >> + * we can send a bus clear command, hoping that the pins will be >> + * released >> + */ >> + if (!(dev->transfer_status & AT91_TWI_SDA) || >> + !(dev->transfer_status & AT91_TWI_SCL)) { >> + dev_dbg(dev->dev, >> + "SDA/SCL are down; sending bus clear command\n"); >> + if (dev->use_alt_cmd) { >> + unsigned int acr; >> + >> + acr = at91_twi_read(dev, AT91_TWI_ACR); >> + acr &= ~AT91_TWI_ACR_DATAL_MASK; >> + at91_twi_write(dev, AT91_TWI_ACR, acr); >> + } >> + at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_CLEAR); > > This bit is not documented on SoCs before SAMA5D2/D4, this write > shouldn't be done unconditionally. > > Indeed, they are not present on SAMA5D4 or earlier SoCs. It is supported on SAMA5D2 though. I will make a new version and implement the CLEAR command only for the SoCs that support it. Thank you for your review. Best regards, Codrin