Antw: Re: Need help to fix some issues with the linux driver "i2c-gpio"

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Jean,

Thank you for the new patch.
I tried it and it works fine for our system with i2c_debug < 2. For
i2c_debug >=2 the debug outputs leads to timeout condition when address
should be acknowledged.

I'll try to publish the "mlx90614" driver after doing some
optimizations. Are you interested to review this driver before, because
it is the first driver we try to publish?

Do plan to include your patch on the "i2c-algo-bit" into the lastest
kernel?
I had applied the patch and done my tests on the 2.6.25.4 kernel, with
a bunch of other patches needed for my system. 

Thanks a lot for your fast and good support for fixing this issue we
had.

Best regards
Matthias Zacharias
matthias.zacharias@xxxxxxxxxxxxxxxx


>>> Jean Delvare <khali@xxxxxxxxxxxx> schrieb am Dienstag, 14. Dezember
2010 um
17:58 in Nachricht <20101214175828.0a62ce3f@xxxxxxxxxxxxxxxx>:
> Hi Matthias,
> 
> On Tue, 14 Dec 2010 15:14:13 +0100, Matthias Zacharias wrote:
>> Thanks for your patch. It is working very well. 
>> But one problem is left:
>>     see "101214_1058_MLX_I2C_patched_0001.bmp" in my dropbox
>> (http://www.dropbox.com/gallery/16457261/1/I2C_2_MLX90614?h=8e2a46)
>> 
>> If between the read command (0x5a.0x6) and the answer (0x5a <3x
>> data_bytes) the timeout condition:  SCL = High for 43Âs match, the
>> MLX90614 go thru reset and returns an invalid value (0xFFFF).
>> 
>> Where can I place the call for "spin_lock_irqsave" and
>> "spin_unlock_irqrestore" to block this timeout situation.
> 
> Ah, I forgot the repeated start condition. The following updated
patch
> fixes this. I have also changed the code to no longer call scllo()
when
> the spinlock is held. That way we can release the spinlock (and thus
> enable interrupts again) faster, which lowers the system latency.
> 
> So please give a try to this new patch, and report.
> 
> * * * * *
> 
> Candidate fix for SCL getting stretched when high resulting in
> slave timeouts.
> 
> Signed-off-by: Jean Delvare <khali@xxxxxxxxxxxx>
> ---
>  drivers/i2c/algos/i2c-algo-bit.c |   33
+++++++++++++++++++++++++++++----
>  include/linux/i2c-algo-bit.h     |    3 +++
>  2 files changed, 32 insertions(+), 4 deletions(-)
> 
> ---
linux-2.6.27.orig/drivers/i2c/algos/i2c-algo-bit.c	2010-12-14
17:34:48.000000000 
> +0100
> +++ linux-2.6.27/drivers/i2c/algos/i2c-algo-bit.c	2010-12-14
17:34:50.000000000 
> +0100
> @@ -30,6 +30,7 @@
>  #include <linux/sched.h>
>  #include <linux/i2c.h>
>  #include <linux/i2c-algo-bit.h>
> +#include <linux/spinlock.h>
>  
>  
>  /* ----- global defines
----------------------------------------------- */
> @@ -131,12 +132,17 @@ static void i2c_start(struct i2c_algo_bi
>  
>  static void i2c_repstart(struct i2c_algo_bit_data *adap)
>  {
> +	unsigned long flags;
> +
>  	/* assert: scl is low */
>  	sdahi(adap);
> +	spin_lock_irqsave(&adap->lockscl, flags);
>  	sclhi(adap);
>  	setsda(adap, 0);
>  	udelay(adap->udelay);
> -	scllo(adap);
> +	setscl(adap, 0);
> +	spin_unlock_irqrestore(&adap->lockscl, flags);
> +	udelay(adap->udelay / 2);
>  }
>  
>  
> @@ -164,15 +170,18 @@ static int i2c_outb(struct i2c_adapter *
>  	int sb;
>  	int ack;
>  	struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
> +	unsigned long flags;
>  
>  	/* assert: scl is low */
>  	for (i = 7; i >= 0; i--) {
>  		sb = (c >> i) & 1;
>  		setsda(adap, sb);
>  		udelay((adap->udelay + 1) / 2);
> +		spin_lock_irqsave(&adap->lockscl, flags);
>  		if (sclhi(adap) < 0) { /* timed out */
>  			bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, "
>  				"timeout at bit #%d\n", (int)c, i);
> +			spin_unlock_irqrestore(&adap->lockscl, flags);
>  			return -ETIMEDOUT;
>  		}
>  		/* FIXME do arbitration here:
> @@ -181,12 +190,16 @@ static int i2c_outb(struct i2c_adapter *
>  		 * Report a unique code, so higher level code can retry
>  		 * the whole (combined) message and *NOT* issue STOP.
>  		 */
> -		scllo(adap);
> +		setscl(adap, 0);
> +		
spin_unlock_irqrestore(&adap->lockscl, flags);
> +		udelay(adap->udelay / 2);
>  	}
>  	sdahi(adap);
> +	spin_lock_irqsave(&adap->lockscl, flags);
>  	if (sclhi(adap) < 0) { /* timeout */
>  		bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, "
>  			"timeout at ack\n", (int)c);
> +		spin_unlock_irqrestore(&adap->lockscl, flags);
>  		return -ETIMEDOUT;
>  	}
>  
> @@ -197,7 +210,9 @@ static int i2c_outb(struct i2c_adapter *
>  	bit_dbg(2, &i2c_adap->dev, "i2c_outb: 0x%02x %s\n", (int)c,
>  		ack ? "A" : "NA");
>  
> -	scllo(adap);
> +	setscl(adap, 0);
> +	spin_unlock_irqrestore(&adap->lockscl, flags);
> +	udelay(adap->udelay / 2);
>  	return ack;
>  	/* assert: scl is low (sda undef) */
>  }
> @@ -210,19 +225,23 @@ static int i2c_inb(struct i2c_adapter *i
>  	int i;
>  	unsigned char indata = 0;
>  	struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
> +	unsigned long flags;
>  
>  	/* assert: scl is low */
>  	sdahi(adap);
>  	for (i = 0; i < 8; i++) {
> +		spin_lock_irqsave(&adap->lockscl, flags);
>  		if (sclhi(adap) < 0) { /* timeout */
>  			bit_dbg(1, &i2c_adap->dev, "i2c_inb: timeout at
bit "
>  				"#%d\n", 7 - i);
> +			spin_unlock_irqrestore(&adap->lockscl, flags);
>  			return -ETIMEDOUT;
>  		}
>  		indata *= 2;
>  		if (getsda(adap))
>  			indata |= 0x01;
>  		setscl(adap, 0);
> +		spin_unlock_irqrestore(&adap->lockscl, flags);
>  		udelay(i == 7 ? adap->udelay / 2 : adap->udelay);
>  	}
>  	/* assert: scl is low */
> @@ -385,16 +404,21 @@ static int sendbytes(struct i2c_adapter 
>  static int acknak(struct i2c_adapter *i2c_adap, int is_ack)
>  {
>  	struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
> +	unsigned long flags;
>  
>  	/* assert: sda is high */
>  	if (is_ack)		/* send ack */
>  		setsda(adap, 0);
>  	udelay((adap->udelay + 1) / 2);
> +	spin_lock_irqsave(&adap->lockscl, flags);
>  	if (sclhi(adap) < 0) {	/* timeout */
>  		dev_err(&i2c_adap->dev, "readbytes: ack/nak
timeout\n");
> +		spin_unlock_irqrestore(&adap->lockscl, flags);
>  		return -ETIMEDOUT;
>  	}
> -	scllo(adap);
> +	setscl(adap, 0);
> +	spin_unlock_irqrestore(&adap->lockscl, flags);
> +	udelay(adap->udelay / 2);
>  	return 0;
>  }
>  
> @@ -603,6 +627,7 @@ static int i2c_bit_prepare_bus(struct i2
>  	}
>  
>  	/* register new adapter to i2c module... */
> +	spin_lock_init(&bit_adap->lockscl);
>  	adap->algo = &i2c_bit_algo;
>  
>  	adap->timeout = 100;	/* default values, should	*/
> --- linux-2.6.27.orig/include/linux/i2c-algo-bit.h	2010-12-14
17:34:49.000000000 
> +0100
> +++ linux-2.6.27/include/linux/i2c-algo-bit.h	2010-12-14
17:35:30.000000000 +0100
> @@ -24,6 +24,8 @@
>  #ifndef _LINUX_I2C_ALGO_BIT_H
>  #define _LINUX_I2C_ALGO_BIT_H
>  
> +#include <linux/spinlock.h>
> +
>  /* --- Defines for bit-adapters
---------------------------------------	*/
>  /*
>   * This struct contains the hw-dependent functions of bit-style
adapters to
> @@ -36,6 +38,7 @@ struct i2c_algo_bit_data {
>  	void (*setscl) (void *data, int state);
>  	int  (*getsda) (void *data);
>  	int  (*getscl) (void *data);
> +	spinlock_t lockscl;
>  
>  	/* local settings */
>  	int udelay;		/* half clock cycle time in us,

--------------------
BMK electronic solutions GmbH
Werner-von-Siemens-Str. 6, Eingang 18 f
D-86159 Augsburg
Tel. +49 (0) 821 / 207 88 - 700
Fax +49 (0) 821 / 207 88 - 721
info@xxxxxxxxxxxxxxxx
GeschÃftsfÃhrer: Dipl.-oec. Alois KnÃferle
Sitz: Augsburg
HR-Nr.: B21197
---------------------

Diese E-mail kann vertrauliche Informationen enthalten. Falls Sie diese
E-Mail irrtÃmlich erhalten haben, informieren Sie bitte unverzÃglich den
Absender und lÃschen Sie diese E-Mail von jedem Rechner, auch von den
Mailservern. Jede Verbreitung des Inhalts, auch die teilweise
Verbreitung, ist in diesem Fall untersagt. AuÃer bei Vorsatz oder grober
FahrlÃssigkeit schliessen wir jegliche Haftung fÃr Verluste oder SchÃden
aus, die durch Viren befallene Software oder E-Mails verursacht werden.

This e-mail may contain confidential
 information. If you received this
e-mail in error, please contact the sender and delete this e-mail from
your computer, including your mailservers. Any dissemination, even
partly, is prohibited. Except in case of gross negligence or wilful
misconduct we accept no liability for any loss or damage caused by
software or e-mail viruses.
--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux GPIO]     [Linux SPI]     [Linux Hardward Monitoring]     [LM Sensors]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux