fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / media / common / saa7146_i2c.c
index 781f23f..8c85efc 100644 (file)
@@ -1,4 +1,3 @@
-#include <linux/version.h>
 #include <media/saa7146_vv.h>
 
 static u32 saa7146_i2c_func(struct i2c_adapter *adapter)
@@ -190,13 +189,21 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
                saa7146_write(dev, I2C_TRANSFER, *dword);
 
                dev->i2c_op = 1;
+               SAA7146_ISR_CLEAR(dev, MASK_16|MASK_17);
                SAA7146_IER_ENABLE(dev, MASK_16|MASK_17);
                saa7146_write(dev, MC2, (MASK_00 | MASK_16));
 
-               wait_event_interruptible(dev->i2c_wq, dev->i2c_op == 0);
-               if (signal_pending (current)) {
-                       /* a signal arrived */
-                       return -ERESTARTSYS;
+               timeout = HZ/100 + 1; /* 10ms */
+               timeout = wait_event_interruptible_timeout(dev->i2c_wq, dev->i2c_op == 0, timeout);
+               if (timeout == -ERESTARTSYS || dev->i2c_op) {
+                       SAA7146_IER_DISABLE(dev, MASK_16|MASK_17);
+                       SAA7146_ISR_CLEAR(dev, MASK_16|MASK_17);
+                       if (timeout == -ERESTARTSYS)
+                               /* a signal arrived */
+                               return -ERESTARTSYS;
+
+                       printk(KERN_WARNING "saa7146_i2c_writeout: timed out waiting for end of xfer\n");
+                       return -EIO;
                }
                status = saa7146_read(dev, I2C_STATUS);
        } else {
@@ -218,11 +225,9 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
                }
                /* wait until we get a transfer done or error */
                timeout = jiffies + HZ/100 + 1; /* 10ms */
+               /* first read usually delivers bogus results... */
+               saa7146_i2c_status(dev);
                while(1) {
-                       /**
-                        *  first read usually delivers bogus results...
-                        */
-                       saa7146_i2c_status(dev);
                        status = saa7146_i2c_status(dev);
                        if ((status & 0x3) != 1)
                                break;
@@ -233,10 +238,10 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
                                DEB_I2C(("saa7146_i2c_writeout: timed out waiting for end of xfer\n"));
                                return -EIO;
                        }
-                       if ((++trial < 20) && short_delay)
+                       if (++trial < 50 && short_delay)
                                udelay(10);
                        else
-                       msleep(1);
+                               msleep(1);
                }
        }
 
@@ -277,10 +282,10 @@ int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *msgs, in
        int i = 0, count = 0;
        u32* buffer = dev->d_i2c.cpu_addr;
        int err = 0;
-        int address_err = 0;
-        int short_delay = 0;
+       int address_err = 0;
+       int short_delay = 0;
 
-       if (down_interruptible (&dev->i2c_lock))
+       if (mutex_lock_interruptible(&dev->i2c_lock))
                return -ERESTARTSYS;
 
        for(i=0;i<num;i++) {
@@ -326,7 +331,7 @@ int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *msgs, in
                                        if( 0 != (SAA7146_USE_I2C_IRQ & dev->ext->flags)) {
                                                goto out;
                                        }
-                                       address_err++;
+                                       address_err++;
                                }
                                DEB_I2C(("error while sending message(s). starting again.\n"));
                                break;
@@ -337,14 +342,14 @@ int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *msgs, in
                        break;
                }
 
-               /* delay a bit before retrying */
-               msleep(10);
+               /* delay a bit before retrying */
+               msleep(10);
 
        } while (err != num && retries--);
 
-        /* if every retry had an address error, exit right away */
-        if (address_err == retries) {
-               goto out;
+       /* if every retry had an address error, exit right away */
+       if (address_err == retries) {
+               goto out;
        }
 
        /* if any things had to be read, get the results */
@@ -367,7 +372,7 @@ out:
                }
        }
 
-       up(&dev->i2c_lock);
+       mutex_unlock(&dev->i2c_lock);
        return err;
 }
 
@@ -387,8 +392,6 @@ static int saa7146_i2c_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, in
 
 /* exported algorithm data */
 static struct i2c_algorithm saa7146_algo = {
-       .name           = "saa7146 i2c algorithm",
-       .id             = I2C_ALGO_SAA7146,
        .master_xfer    = saa7146_i2c_xfer,
        .functionality  = saa7146_i2c_func,
 };
@@ -404,15 +407,12 @@ int saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c
        saa7146_i2c_reset(dev);
 
        if( NULL != i2c_adapter ) {
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-               i2c_adapter->data = dev;
-#else
                BUG_ON(!i2c_adapter->class);
                i2c_set_adapdata(i2c_adapter,dev);
-#endif
+               i2c_adapter->dev.parent    = &dev->pci->dev;
                i2c_adapter->algo          = &saa7146_algo;
                i2c_adapter->algo_data     = NULL;
-               i2c_adapter->id            = I2C_ALGO_SAA7146;
+               i2c_adapter->id            = I2C_HW_SAA7146;
                i2c_adapter->timeout = SAA7146_I2C_TIMEOUT;
                i2c_adapter->retries = SAA7146_I2C_RETRIES;
        }