From 30091404af5a7cd515e7b565df76932e295d8f6f Mon Sep 17 00:00:00 2001 From: David Miller Date: Wed, 22 Oct 2008 20:21:30 +0200 Subject: [PATCH] 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 Signed-off-by: Jean Delvare --- drivers/i2c/algos/i2c-algo-pcf.c | 17 +++++++++++++---- include/linux/i2c-algo-pcf.h | 3 +++ 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 a8a5b6d1dd8..b8a6f3bcbae 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, int i; int ret=0, timeout, status; + if (adap->xfer_begin) + adap->xfer_begin(adap->data); /* Check for bus busy */ timeout = wait_for_bb(adap); if (timeout) { DEB2(printk(KERN_ERR "i2c-algo-pcf.o: " "Timeout waiting for BB in pcf_xfer\n");) - return -EIO; + i = -EIO; + goto out; } for (i = 0;ret >= 0 && i < num; i++) { @@ -359,12 +362,14 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap, if (timeout) { if (timeout == -EINTR) { /* arbitration lost */ - return (-EINTR); + i = -EINTR; + goto out; } i2c_stop(adap); DEB2(printk(KERN_ERR "i2c-algo-pcf.o: Timeout waiting " "for PIN(1) in pcf_xfer\n");) - return (-EREMOTEIO); + i = -EREMOTEIO; + goto out; } #ifndef STUB_I2C @@ -372,7 +377,8 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap, if (status & I2C_PCF_LRB) { i2c_stop(adap); DEB2(printk(KERN_ERR "i2c-algo-pcf.o: No LRB(1) in pcf_xfer\n");) - return (-EREMOTEIO); + i = -EREMOTEIO; + goto out; } #endif @@ -404,6 +410,9 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap, } } +out: + if (adap->xfer_end) + adap->xfer_end(adap->data); return (i); } diff --git a/include/linux/i2c-algo-pcf.h b/include/linux/i2c-algo-pcf.h index 5de8a319bf1..0f91a957a69 100644 --- a/include/linux/i2c-algo-pcf.h +++ b/include/linux/i2c-algo-pcf.h @@ -33,6 +33,9 @@ struct i2c_algo_pcf_data { int (*getclock) (void *data); void (*waitforpin) (void *data); + void (*xfer_begin) (void *data); + void (*xfer_end) (void *data); + /* Multi-master lost arbitration back-off delay (msecs) * This should be set by the bus adapter or knowledgable client * if bus is multi-mastered, else zero -- 2.41.1