aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/algos
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2007-05-01 17:26:28 -0400
committerJean Delvare <khali@hyperion.delvare>2007-05-01 17:26:28 -0400
commit1ecac07abaca1a4084d0259d4a15b55188852a2e (patch)
tree369572a568a1162ed4ce7e3ef656f36e7e379a6b /drivers/i2c/algos
parentef2c8321f5a27ff9ecdae1ee587430cafa495586 (diff)
i2c-algo-bit: Always send a stop condition before leaving
The i2c-algo-bit driver doesn't behave well on read errors: it'll bail out without even sending a stop condition on the bus, so the bus will be stuck. So make sure that we always send a stop condition on the bus before we leave. The best way to make sure is to always send it at the end of function bit_xfer. Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/i2c/algos')
-rw-r--r--drivers/i2c/algos/i2c-algo-bit.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c
index 95aa5395a5be..28b7e25ca79c 100644
--- a/drivers/i2c/algos/i2c-algo-bit.c
+++ b/drivers/i2c/algos/i2c-algo-bit.c
@@ -312,12 +312,10 @@ static int try_address(struct i2c_adapter *i2c_adap,
312 int i,ret = -1; 312 int i,ret = -1;
313 for (i=0;i<=retries;i++) { 313 for (i=0;i<=retries;i++) {
314 ret = i2c_outb(i2c_adap,addr); 314 ret = i2c_outb(i2c_adap,addr);
315 if (ret==1) 315 if (ret == 1 || i == retries)
316 break; /* success! */ 316 break;
317 i2c_stop(adap); 317 i2c_stop(adap);
318 udelay(5/*adap->udelay*/); 318 udelay(5/*adap->udelay*/);
319 if (i==retries) /* no success */
320 break;
321 i2c_start(adap); 319 i2c_start(adap);
322 udelay(adap->udelay); 320 udelay(adap->udelay);
323 } 321 }
@@ -331,7 +329,6 @@ static int try_address(struct i2c_adapter *i2c_adap,
331 329
332static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) 330static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
333{ 331{
334 struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
335 char c; 332 char c;
336 const char *temp = msg->buf; 333 const char *temp = msg->buf;
337 int count = msg->len; 334 int count = msg->len;
@@ -349,7 +346,6 @@ static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
349 wrcount++; 346 wrcount++;
350 } else { /* arbitration or no acknowledge */ 347 } else { /* arbitration or no acknowledge */
351 dev_err(&i2c_adap->dev, "sendbytes: error - bailout.\n"); 348 dev_err(&i2c_adap->dev, "sendbytes: error - bailout.\n");
352 i2c_stop(adap);
353 return (retval<0)? retval : -EFAULT; 349 return (retval<0)? retval : -EFAULT;
354 /* got a better one ?? */ 350 /* got a better one ?? */
355 } 351 }
@@ -480,27 +476,34 @@ static int bit_xfer(struct i2c_adapter *i2c_adap,
480 if ((ret != 0) && !nak_ok) { 476 if ((ret != 0) && !nak_ok) {
481 DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: NAK from device addr %2.2x msg #%d\n" 477 DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: NAK from device addr %2.2x msg #%d\n"
482 ,msgs[i].addr,i)); 478 ,msgs[i].addr,i));
483 return (ret<0) ? ret : -EREMOTEIO; 479 goto bailout;
484 } 480 }
485 } 481 }
486 if (pmsg->flags & I2C_M_RD ) { 482 if (pmsg->flags & I2C_M_RD ) {
487 /* read bytes into buffer*/ 483 /* read bytes into buffer*/
488 ret = readbytes(i2c_adap, pmsg); 484 ret = readbytes(i2c_adap, pmsg);
489 DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: read %d bytes.\n",ret)); 485 DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: read %d bytes.\n",ret));
490 if (ret < pmsg->len ) { 486 if (ret < pmsg->len) {
491 return (ret<0)? ret : -EREMOTEIO; 487 if (ret >= 0)
488 ret = -EREMOTEIO;
489 goto bailout;
492 } 490 }
493 } else { 491 } else {
494 /* write bytes from buffer */ 492 /* write bytes from buffer */
495 ret = sendbytes(i2c_adap, pmsg); 493 ret = sendbytes(i2c_adap, pmsg);
496 DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: wrote %d bytes.\n",ret)); 494 DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: wrote %d bytes.\n",ret));
497 if (ret < pmsg->len ) { 495 if (ret < pmsg->len) {
498 return (ret<0) ? ret : -EREMOTEIO; 496 if (ret >= 0)
497 ret = -EREMOTEIO;
498 goto bailout;
499 } 499 }
500 } 500 }
501 } 501 }
502 ret = i;
503
504bailout:
502 i2c_stop(adap); 505 i2c_stop(adap);
503 return num; 506 return ret;
504} 507}
505 508
506static u32 bit_func(struct i2c_adapter *adap) 509static u32 bit_func(struct i2c_adapter *adap)