Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

i2c-algo-pcf: Add adapter hooks around xfer begin and end

Some I2C bus implementations need to synchronize with external
entities, such as system firmware, which might also be programming the
same I2C bus.

In order to facilitate this add ->xfer_begin() and ->xfer_end() hooks
which are invoked around pcf_xfer().

[JD: Make these hooks optional.]

Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jean Delvare <khali@linux-fr.org>

authored by

David Miller and committed by
Jean Delvare
30091404 08e5338d

+16 -4
+13 -4
drivers/i2c/algos/i2c-algo-pcf.c
··· 331 331 int i; 332 332 int ret=0, timeout, status; 333 333 334 + if (adap->xfer_begin) 335 + adap->xfer_begin(adap->data); 334 336 335 337 /* Check for bus busy */ 336 338 timeout = wait_for_bb(adap); 337 339 if (timeout) { 338 340 DEB2(printk(KERN_ERR "i2c-algo-pcf.o: " 339 341 "Timeout waiting for BB in pcf_xfer\n");) 340 - return -EIO; 342 + i = -EIO; 343 + goto out; 341 344 } 342 345 343 346 for (i = 0;ret >= 0 && i < num; i++) { ··· 362 359 if (timeout) { 363 360 if (timeout == -EINTR) { 364 361 /* arbitration lost */ 365 - return (-EINTR); 362 + i = -EINTR; 363 + goto out; 366 364 } 367 365 i2c_stop(adap); 368 366 DEB2(printk(KERN_ERR "i2c-algo-pcf.o: Timeout waiting " 369 367 "for PIN(1) in pcf_xfer\n");) 370 - return (-EREMOTEIO); 368 + i = -EREMOTEIO; 369 + goto out; 371 370 } 372 371 373 372 #ifndef STUB_I2C ··· 377 372 if (status & I2C_PCF_LRB) { 378 373 i2c_stop(adap); 379 374 DEB2(printk(KERN_ERR "i2c-algo-pcf.o: No LRB(1) in pcf_xfer\n");) 380 - return (-EREMOTEIO); 375 + i = -EREMOTEIO; 376 + goto out; 381 377 } 382 378 #endif 383 379 ··· 410 404 } 411 405 } 412 406 407 + out: 408 + if (adap->xfer_end) 409 + adap->xfer_end(adap->data); 413 410 return (i); 414 411 } 415 412
+3
include/linux/i2c-algo-pcf.h
··· 33 33 int (*getclock) (void *data); 34 34 void (*waitforpin) (void *data); 35 35 36 + void (*xfer_begin) (void *data); 37 + void (*xfer_end) (void *data); 38 + 36 39 /* Multi-master lost arbitration back-off delay (msecs) 37 40 * This should be set by the bus adapter or knowledgable client 38 41 * if bus is multi-mastered, else zero