summaryrefslogtreecommitdiffstats
path: root/drivers/media/common/saa7146_i2c.c
diff options
context:
space:
mode:
authorHartmut Birr <e9hack@googlemail.com>2006-11-01 13:01:42 -0300
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-12-10 09:05:34 -0200
commit35e55255bbe1775c3cdb5d9cff494d72d5a49bf3 (patch)
tree20846c296d0d4c7c7335cd5b55a2440e47ef4eed /drivers/media/common/saa7146_i2c.c
parent88bbdf74fcfa7ed1fd1a3c825ee5575752344326 (diff)
V4L/DVB (4915): Saa7146: Add timeout protection for I2C interrupt
Add a timeout to the wait for the i2c-interrupt. The timeout prevents from endless waiting if the interrupt gets lost. Signed-off-by: Hartmut Birr <e9hack@googlemail.com> Signed-off-by: Oliver Endriss <o.endriss@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/common/saa7146_i2c.c')
-rw-r--r--drivers/media/common/saa7146_i2c.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c
index 5297a365c92..8c85efc2652 100644
--- a/drivers/media/common/saa7146_i2c.c
+++ b/drivers/media/common/saa7146_i2c.c
@@ -189,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 {