Hi Matel, Thanks for posting this patch. See comments below.. I'll be happy to test your changes once the following items are clarified. > The pathch is against 2.6.28.2, but it should apply to the > cureent GIT version as well. This patch needs to be re-based against the latest version of the driver as it has changes that this patch will revert or won't apply to. > > Signed-off-by: Matej Kupljen <matej.kupljen@xxxxxxxxx> > > --- i2c-pnx-orig.c 2010-12-14 17:48:40.000000000 +0100 > +++ i2c-pnx.c 2011-02-01 23:48:42.000000000 +0100 > @@ -54,7 +54,8 @@ > { > struct i2c_pnx_algo_data *data = adap->algo_data; > struct timer_list *timer = &data->mif.timer; > - int expires = I2C_PNX_TIMEOUT / (1000 / HZ); > + // We should probably take into account, how many bytes we need to > transfer! Use /* */ for comments instead of // Regarding this comment, you should remove it or add some support for size based timeouts. The minimum timeout with the latest updates will always be 10mS waiting for a stop condition or the bus to clear, but the timeout doesn't come into play for the actual transfer. > + int expires = I2C_PNX_TIMEOUT * 10 / (1000 / HZ); The logic for handling timeout was changed in a later version of i2c-pnx driver. This might of already fixed the timeout issue. > > del_timer_sync(timer); > > @@ -74,7 +75,7 @@ > * > * Generate a START signal in the desired mode. > */ > -static int i2c_pnx_start(unsigned char slave_addr, struct i2c_adapter > *adap) > +static int i2c_pnx_start(unsigned char slave_addr, struct i2c_adapter > *adap, int repeated) > { > struct i2c_pnx_algo_data *alg_data = adap->algo_data; > > @@ -89,8 +90,8 @@ > return -EINVAL; > } > > - /* First, make sure bus is idle */ > - if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) { > + /* First, make sure bus is idle, if we are not doing repeated start > */ > + if ((!repeated) && (wait_timeout(I2C_PNX_TIMEOUT, alg_data))) { > /* Somebody else is monopolizing the bus */ > dev_err(&adap->dev, "%s: Bus busy. Slave addr = %02x, " > "cntrl = %x, stat = %x\n", > @@ -439,7 +440,7 @@ > i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) > { > struct i2c_msg *pmsg; > - int rc = 0, completed = 0, i; > + int rc = 0, completed = 0, i, repeated; > struct i2c_pnx_algo_data *alg_data = adap->algo_data; > u32 stat = ioread32(I2C_REG_STS(alg_data)); > > @@ -454,6 +455,7 @@ > > pmsg = &msgs[i]; > addr = pmsg->addr; > + repeated = 0; > > if (pmsg->flags & I2C_M_TEN) { > dev_err(&adap->dev, > @@ -479,16 +481,22 @@ > /* initialize the completion var */ > init_completion(&alg_data->mif.complete); > > - /* Enable master interrupt */ > - iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_afie | > - mcntrl_naie | mcntrl_drmie, > - I2C_REG_CTL(alg_data)); > + /* If this is not the only message, then we need to > + * send repeated start, but only if the flaga allow us > + */ Comments than span multiple lines should be in the format /* * Line 1 * Line 2 */ Single comment lines are in the format /* Line 1 */ 'Flaga allow us' should be 'flag allows it' > + if((i > 0) && !(pmsg->flags & I2C_M_NOSTART)) > + repeated = 1; All the repeated start logic seems like it will work ok. > > /* Put start-code and slave-address on the bus. */ > - rc = i2c_pnx_start(addr, adap); > + rc = i2c_pnx_start(addr, adap, repeated); ÿô.nÇ·®+%˱é¥wÿº{.nÇ·¥{±þ-þ)íèjg¬±¨¶Ýjÿ¾«þG«é¸¢·¦j:+v¨wèm¶ÿþø®w¥þ࣢·hâÿÙ