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>
        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++) {
                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
                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
     
                }
        }
 
+out:
+       if (adap->xfer_end)
+               adap->xfer_end(adap->data);
        return (i);
 }
 
 
        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