X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmedia%2Fcommon%2Fsaa7146_i2c.c;h=8c85efc26527fe9bf5bdd85473f014b568871876;hb=refs%2Fheads%2Fvserver;hp=781f23f0cbcc597e79363d230cda2872908b06e3;hpb=f7f1b0f1e2fbadeab12d24236000e778aa9b1ead;p=linux-2.6.git diff --git a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c index 781f23f0c..8c85efc26 100644 --- a/drivers/media/common/saa7146_i2c.c +++ b/drivers/media/common/saa7146_i2c.c @@ -1,4 +1,3 @@ -#include #include 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;iext->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; }