summaryrefslogtreecommitdiff
path: root/linux
diff options
context:
space:
mode:
Diffstat (limited to 'linux')
-rw-r--r--linux/drivers/media/common/saa7146_core.c8
-rw-r--r--linux/drivers/media/common/saa7146_i2c.c13
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 {