Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Hartmut Birr and committed by
Mauro Carvalho Chehab
35e55255 88bbdf74

+12 -4
+12 -4
drivers/media/common/saa7146_i2c.c
··· 189 189 saa7146_write(dev, I2C_TRANSFER, *dword); 190 190 191 191 dev->i2c_op = 1; 192 + SAA7146_ISR_CLEAR(dev, MASK_16|MASK_17); 192 193 SAA7146_IER_ENABLE(dev, MASK_16|MASK_17); 193 194 saa7146_write(dev, MC2, (MASK_00 | MASK_16)); 194 195 195 - wait_event_interruptible(dev->i2c_wq, dev->i2c_op == 0); 196 - if (signal_pending (current)) { 197 - /* a signal arrived */ 198 - return -ERESTARTSYS; 196 + timeout = HZ/100 + 1; /* 10ms */ 197 + timeout = wait_event_interruptible_timeout(dev->i2c_wq, dev->i2c_op == 0, timeout); 198 + if (timeout == -ERESTARTSYS || dev->i2c_op) { 199 + SAA7146_IER_DISABLE(dev, MASK_16|MASK_17); 200 + SAA7146_ISR_CLEAR(dev, MASK_16|MASK_17); 201 + if (timeout == -ERESTARTSYS) 202 + /* a signal arrived */ 203 + return -ERESTARTSYS; 204 + 205 + printk(KERN_WARNING "saa7146_i2c_writeout: timed out waiting for end of xfer\n"); 206 + return -EIO; 199 207 } 200 208 status = saa7146_read(dev, I2C_STATUS); 201 209 } else {