aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/i2c/algos/i2c-algo-pcf.c17
-rw-r--r--include/linux/i2c-algo-pcf.h3
2 files changed, 16 insertions, 4 deletions
diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c
index a8a5b6d1dd88..b8a6f3bcbae3 100644
--- a/drivers/i2c/algos/i2c-algo-pcf.c
+++ b/drivers/i2c/algos/i2c-algo-pcf.c
@@ -331,13 +331,16 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap,
331 int i; 331 int i;
332 int ret=0, timeout, status; 332 int ret=0, timeout, status;
333 333
334 if (adap->xfer_begin)
335 adap->xfer_begin(adap->data);
334 336
335 /* Check for bus busy */ 337 /* Check for bus busy */
336 timeout = wait_for_bb(adap); 338 timeout = wait_for_bb(adap);
337 if (timeout) { 339 if (timeout) {
338 DEB2(printk(KERN_ERR "i2c-algo-pcf.o: " 340 DEB2(printk(KERN_ERR "i2c-algo-pcf.o: "
339 "Timeout waiting for BB in pcf_xfer\n");) 341 "Timeout waiting for BB in pcf_xfer\n");)
340 return -EIO; 342 i = -EIO;
343 goto out;
341 } 344 }
342 345
343 for (i = 0;ret >= 0 && i < num; i++) { 346 for (i = 0;ret >= 0 && i < num; i++) {
@@ -359,12 +362,14 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap,
359 if (timeout) { 362 if (timeout) {
360 if (timeout == -EINTR) { 363 if (timeout == -EINTR) {
361 /* arbitration lost */ 364 /* arbitration lost */
362 return (-EINTR); 365 i = -EINTR;
366 goto out;
363 } 367 }
364 i2c_stop(adap); 368 i2c_stop(adap);
365 DEB2(printk(KERN_ERR "i2c-algo-pcf.o: Timeout waiting " 369 DEB2(printk(KERN_ERR "i2c-algo-pcf.o: Timeout waiting "
366 "for PIN(1) in pcf_xfer\n");) 370 "for PIN(1) in pcf_xfer\n");)
367 return (-EREMOTEIO); 371 i = -EREMOTEIO;
372 goto out;
368 } 373 }
369 374
370#ifndef STUB_I2C 375#ifndef STUB_I2C
@@ -372,7 +377,8 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap,
372 if (status & I2C_PCF_LRB) { 377 if (status & I2C_PCF_LRB) {
373 i2c_stop(adap); 378 i2c_stop(adap);
374 DEB2(printk(KERN_ERR "i2c-algo-pcf.o: No LRB(1) in pcf_xfer\n");) 379 DEB2(printk(KERN_ERR "i2c-algo-pcf.o: No LRB(1) in pcf_xfer\n");)
375 return (-EREMOTEIO); 380 i = -EREMOTEIO;
381 goto out;
376 } 382 }
377#endif 383#endif
378 384
@@ -404,6 +410,9 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap,
404 } 410 }
405 } 411 }
406 412
413out:
414 if (adap->xfer_end)
415 adap->xfer_end(adap->data);
407 return (i); 416 return (i);
408} 417}
409 418
diff --git a/include/linux/i2c-algo-pcf.h b/include/linux/i2c-algo-pcf.h
index 5de8a319bf14..0f91a957a690 100644
--- a/include/linux/i2c-algo-pcf.h
+++ b/include/linux/i2c-algo-pcf.h
@@ -33,6 +33,9 @@ struct i2c_algo_pcf_data {
33 int (*getclock) (void *data); 33 int (*getclock) (void *data);
34 void (*waitforpin) (void *data); 34 void (*waitforpin) (void *data);
35 35
36 void (*xfer_begin) (void *data);
37 void (*xfer_end) (void *data);
38
36 /* Multi-master lost arbitration back-off delay (msecs) 39 /* Multi-master lost arbitration back-off delay (msecs)
37 * This should be set by the bus adapter or knowledgable client 40 * This should be set by the bus adapter or knowledgable client
38 * if bus is multi-mastered, else zero 41 * if bus is multi-mastered, else zero