linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: [PATCH] i2c: at91: Send bus clear command if SCL or SDA is down
       [not found] <20190911095854.5141-1-codrin.ciubotariu@microchip.com>
@ 2019-09-14 19:05 ` Ludovic Desroches
  2019-09-16  5:20 ` Claudiu.Beznea
  2019-09-19 15:06 ` kbouhara
  2 siblings, 0 replies; 4+ messages in thread
From: Ludovic Desroches @ 2019-09-14 19:05 UTC (permalink / raw)
  To: Codrin Ciubotariu
  Cc: linux-i2c, linux-arm-kernel, linux-kernel, nicolas.ferre,
	alexandre.belloni, wsa

On Wed, Sep 11, 2019 at 12:58:54PM +0300, 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@microchip.com>
Acked-by: Ludovic Desroches <ludovic.desroches@microchip.com>

I'll be off for three weeks so if there are minor changes, you can keep my
ack.

Thanks

Ludovic

> ---
>  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);
> +	}
> +
>  	return ret;
>  }
>  
> diff --git a/drivers/i2c/busses/i2c-at91.h b/drivers/i2c/busses/i2c-at91.h
> index 499b506f6128..ffb870f3ffc6 100644
> --- a/drivers/i2c/busses/i2c-at91.h
> +++ b/drivers/i2c/busses/i2c-at91.h
> @@ -36,6 +36,7 @@
>  #define	AT91_TWI_SVDIS		BIT(5)	/* Slave Transfer Disable */
>  #define	AT91_TWI_QUICK		BIT(6)	/* SMBus quick command */
>  #define	AT91_TWI_SWRST		BIT(7)	/* Software Reset */
> +#define	AT91_TWI_CLEAR		BIT(15) /* Bus clear command */
>  #define	AT91_TWI_ACMEN		BIT(16) /* Alternative Command Mode Enable */
>  #define	AT91_TWI_ACMDIS		BIT(17) /* Alternative Command Mode Disable */
>  #define	AT91_TWI_THRCLR		BIT(24) /* Transmit Holding Register Clear */
> @@ -69,6 +70,8 @@
>  #define	AT91_TWI_NACK		BIT(8)	/* Not Acknowledged */
>  #define	AT91_TWI_EOSACC		BIT(11)	/* End Of Slave Access */
>  #define	AT91_TWI_LOCK		BIT(23) /* TWI Lock due to Frame Errors */
> +#define	AT91_TWI_SCL		BIT(24) /* TWI SCL status */
> +#define	AT91_TWI_SDA		BIT(25) /* TWI SDA status */
>  
>  #define	AT91_TWI_INT_MASK \
>  	(AT91_TWI_TXCOMP | AT91_TWI_RXRDY | AT91_TWI_TXRDY | AT91_TWI_NACK \
> @@ -81,7 +84,8 @@
>  #define	AT91_TWI_THR		0x0034	/* Transmit Holding Register */
>  
>  #define	AT91_TWI_ACR		0x0040	/* Alternative Command Register */
> -#define	AT91_TWI_ACR_DATAL(len)	((len) & 0xff)
> +#define	AT91_TWI_ACR_DATAL_MASK	GENMASK(15, 0)
> +#define	AT91_TWI_ACR_DATAL(len)	((len) & AT91_TWI_ACR_DATAL_MASK)
>  #define	AT91_TWI_ACR_DIR	BIT(8)
>  
>  #define	AT91_TWI_FMR		0x0050	/* FIFO Mode Register */
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] i2c: at91: Send bus clear command if SCL or SDA is down
       [not found] <20190911095854.5141-1-codrin.ciubotariu@microchip.com>
  2019-09-14 19:05 ` [PATCH] i2c: at91: Send bus clear command if SCL or SDA is down Ludovic Desroches
@ 2019-09-16  5:20 ` Claudiu.Beznea
  2019-09-19 15:06 ` kbouhara
  2 siblings, 0 replies; 4+ messages in thread
From: Claudiu.Beznea @ 2019-09-16  5:20 UTC (permalink / raw)
  To: Codrin.Ciubotariu, linux-i2c, linux-arm-kernel, linux-kernel
  Cc: Ludovic.Desroches, alexandre.belloni, wsa



On 11.09.2019 12:58, Codrin Ciubotariu wrote:
> External E-Mail
> 
> 
> 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@microchip.com>

Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com>

> ---
>  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);
> +	}
> +
>  	return ret;
>  }
>  
> diff --git a/drivers/i2c/busses/i2c-at91.h b/drivers/i2c/busses/i2c-at91.h
> index 499b506f6128..ffb870f3ffc6 100644
> --- a/drivers/i2c/busses/i2c-at91.h
> +++ b/drivers/i2c/busses/i2c-at91.h
> @@ -36,6 +36,7 @@
>  #define	AT91_TWI_SVDIS		BIT(5)	/* Slave Transfer Disable */
>  #define	AT91_TWI_QUICK		BIT(6)	/* SMBus quick command */
>  #define	AT91_TWI_SWRST		BIT(7)	/* Software Reset */
> +#define	AT91_TWI_CLEAR		BIT(15) /* Bus clear command */
>  #define	AT91_TWI_ACMEN		BIT(16) /* Alternative Command Mode Enable */
>  #define	AT91_TWI_ACMDIS		BIT(17) /* Alternative Command Mode Disable */
>  #define	AT91_TWI_THRCLR		BIT(24) /* Transmit Holding Register Clear */
> @@ -69,6 +70,8 @@
>  #define	AT91_TWI_NACK		BIT(8)	/* Not Acknowledged */
>  #define	AT91_TWI_EOSACC		BIT(11)	/* End Of Slave Access */
>  #define	AT91_TWI_LOCK		BIT(23) /* TWI Lock due to Frame Errors */
> +#define	AT91_TWI_SCL		BIT(24) /* TWI SCL status */
> +#define	AT91_TWI_SDA		BIT(25) /* TWI SDA status */
>  
>  #define	AT91_TWI_INT_MASK \
>  	(AT91_TWI_TXCOMP | AT91_TWI_RXRDY | AT91_TWI_TXRDY | AT91_TWI_NACK \
> @@ -81,7 +84,8 @@
>  #define	AT91_TWI_THR		0x0034	/* Transmit Holding Register */
>  
>  #define	AT91_TWI_ACR		0x0040	/* Alternative Command Register */
> -#define	AT91_TWI_ACR_DATAL(len)	((len) & 0xff)
> +#define	AT91_TWI_ACR_DATAL_MASK	GENMASK(15, 0)
> +#define	AT91_TWI_ACR_DATAL(len)	((len) & AT91_TWI_ACR_DATAL_MASK)
>  #define	AT91_TWI_ACR_DIR	BIT(8)
>  
>  #define	AT91_TWI_FMR		0x0050	/* FIFO Mode Register */
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] i2c: at91: Send bus clear command if SCL or SDA is down
       [not found] <20190911095854.5141-1-codrin.ciubotariu@microchip.com>
  2019-09-14 19:05 ` [PATCH] i2c: at91: Send bus clear command if SCL or SDA is down Ludovic Desroches
  2019-09-16  5:20 ` Claudiu.Beznea
@ 2019-09-19 15:06 ` kbouhara
  2019-09-19 16:25   ` Codrin.Ciubotariu
  2 siblings, 1 reply; 4+ messages in thread
From: kbouhara @ 2019-09-19 15:06 UTC (permalink / raw)
  To: Codrin Ciubotariu, linux-i2c, linux-arm-kernel, linux-kernel
  Cc: ludovic.desroches, nicolas.ferre, alexandre.belloni, wsa

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@microchip.com>
> ---
>   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.


-- 
Kamel Bouhara, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] i2c: at91: Send bus clear command if SCL or SDA is down
  2019-09-19 15:06 ` kbouhara
@ 2019-09-19 16:25   ` Codrin.Ciubotariu
  0 siblings, 0 replies; 4+ messages in thread
From: Codrin.Ciubotariu @ 2019-09-19 16:25 UTC (permalink / raw)
  To: kamel.bouhara, linux-i2c, linux-arm-kernel, linux-kernel
  Cc: Ludovic.Desroches, Nicolas.Ferre, alexandre.belloni, wsa

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@microchip.com>
>> ---
>>   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

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-09-19 16:25 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20190911095854.5141-1-codrin.ciubotariu@microchip.com>
2019-09-14 19:05 ` [PATCH] i2c: at91: Send bus clear command if SCL or SDA is down Ludovic Desroches
2019-09-16  5:20 ` Claudiu.Beznea
2019-09-19 15:06 ` kbouhara
2019-09-19 16:25   ` Codrin.Ciubotariu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).