diff options
Diffstat (limited to 'linux/drivers/media')
-rw-r--r-- | linux/drivers/media/common/saa7146_core.c | 8 | ||||
-rw-r--r-- | linux/drivers/media/common/saa7146_i2c.c | 13 |
2 files changed, 16 insertions, 5 deletions
diff --git a/linux/drivers/media/common/saa7146_core.c b/linux/drivers/media/common/saa7146_core.c index 50ed45496..46ce10842 100644 --- a/linux/drivers/media/common/saa7146_core.c +++ b/linux/drivers/media/common/saa7146_core.c @@ -386,7 +386,6 @@ static void interrupt_hw(int irq, void *dev_id, struct pt_regs *regs) } if (0 != (isr & (MASK_16|MASK_17))) { u32 status = saa7146_read(dev, I2C_STATUS); - isr &= ~(MASK_16|MASK_17); if( (0x3 == (status & 0x3)) || (0 == (status & 0x1)) ) { IER_DISABLE(dev, MASK_16|MASK_17); /* only wake up if we expect something */ @@ -394,10 +393,15 @@ static void interrupt_hw(int irq, void *dev_id, struct pt_regs *regs) u32 psr = (saa7146_read(dev, PSR) >> 16) & 0x2; u32 ssr = (saa7146_read(dev, SSR) >> 17) & 0x1f; DEB_I2C(("irq: i2c, status: 0x%08x, psr:0x%02x, ssr:0x%02x).\n",status,psr,ssr)); - wake_up(&dev->i2c_wq); dev->i2c_op = 0; + wake_up(&dev->i2c_wq); } + else + DEB_I2C(("unexpected irq: i2c, status: 0x%08x, isr %#x\n",status, isr)); } + else + DEB_I2C(("unhandled irq: i2c, status: 0x%08x, isr %#x\n",status, isr)); + isr &= ~(MASK_16|MASK_17); } if( 0 != isr ) { ERR(("warning: interrupt enabled, but not handled properly.(0x%08x)\n",isr)); diff --git a/linux/drivers/media/common/saa7146_i2c.c b/linux/drivers/media/common/saa7146_i2c.c index 1b3455dac..8a8c86265 100644 --- a/linux/drivers/media/common/saa7146_i2c.c +++ b/linux/drivers/media/common/saa7146_i2c.c @@ -198,6 +198,7 @@ int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword) { int i = 0; u32 status = 0, mc2 = 0; + const int timeout = SAA7146_I2C_TIMEOUT * HZ / 1000; /* write out i2c-command */ if( 0 != use_i2c_irq ) { @@ -206,13 +207,19 @@ if( 0 != use_i2c_irq ) { saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate); saa7146_write(dev, I2C_TRANSFER, *dword); - IER_ENABLE(dev, MASK_16|MASK_17); + IER_ENABLE(dev, MASK_17); saa7146_write(dev, MC2, (MASK_00 | MASK_16)); - wait_event_interruptible(dev->i2c_wq, (0 == dev->i2c_op) ); + interruptible_sleep_on_timeout(&dev->i2c_wq, timeout); if( 0 != dev->i2c_op ) { - printk("saa7146: bogus i2c stuff happened.\n"); + DEB_I2C(("error: i2c timeout\n")); dev->i2c_op = 0; + status = saa7146_read(dev, I2C_STATUS); + if( 0 != (status & SAA7146_I2C_APERR) ) { + DEB_I2C(("timeout in address phase.\n")); + return -2; + } + return -1; } status = saa7146_read(dev, I2C_STATUS); } else { |