V4L/DVB (5987): saa7146: clean-up irq processing
authorOliver Endriss <o.endriss@gmx.de>
Thu, 9 Aug 2007 05:41:16 +0000 (02:41 -0300)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Wed, 10 Oct 2007 01:04:44 +0000 (22:04 -0300)
Interrupt processing fixed: First handle interrupt, then acknowledge it.
Otherwise the same interrupt might occur twice.
Cleaned-up i2c interrupt handler and i2c error messages.

Signed-off-by: Oliver Endriss <o.endriss@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
drivers/media/common/saa7146_core.c
drivers/media/common/saa7146_i2c.c

index 12cda9eebd12a83df3b0a6c89d9cbb03adb15f86..1c962a2b44df3f0a2d6e78fbd67ecee8f433fc47 100644 (file)
@@ -248,10 +248,11 @@ int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt
 static irqreturn_t interrupt_hw(int irq, void *dev_id)
 {
        struct saa7146_dev *dev = dev_id;
-       u32 isr = 0;
+       u32 isr;
+       u32 ack_isr;
 
        /* read out the interrupt status register */
-       isr = saa7146_read(dev, ISR);
+       ack_isr = isr = saa7146_read(dev, ISR);
 
        /* is this our interrupt? */
        if ( 0 == isr ) {
@@ -259,8 +260,6 @@ static irqreturn_t interrupt_hw(int irq, void *dev_id)
                return IRQ_NONE;
        }
 
-       saa7146_write(dev, ISR, isr);
-
        if( 0 != (dev->ext)) {
                if( 0 != (dev->ext->irq_mask & isr )) {
                        if( 0 != dev->ext->irq_func ) {
@@ -283,21 +282,16 @@ static irqreturn_t interrupt_hw(int irq, void *dev_id)
                isr &= ~MASK_28;
        }
        if (0 != (isr & (MASK_16|MASK_17))) {
-               u32 status = saa7146_read(dev, I2C_STATUS);
-               if( (0x3 == (status & 0x3)) || (0 == (status & 0x1)) ) {
-                       SAA7146_IER_DISABLE(dev, MASK_16|MASK_17);
-                       /* only wake up if we expect something */
-                       if( 0 != dev->i2c_op ) {
-                               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));
-                               dev->i2c_op = 0;
-                               wake_up(&dev->i2c_wq);
-                       } else {
-                               DEB_I2C(("unexpected irq: i2c, status: 0x%08x, isr %#x\n",status, isr));
-                       }
+               SAA7146_IER_DISABLE(dev, MASK_16|MASK_17);
+               /* only wake up if we expect something */
+               if (0 != dev->i2c_op) {
+                       dev->i2c_op = 0;
+                       wake_up(&dev->i2c_wq);
                } else {
-                       DEB_I2C(("unhandled irq: i2c, status: 0x%08x, isr %#x\n",status, isr));
+                       u32 psr = saa7146_read(dev, PSR);
+                       u32 ssr = saa7146_read(dev, SSR);
+                       printk(KERN_WARNING "%s: unexpected i2c irq: isr %08x psr %08x ssr %08x\n",
+                              dev->name, isr, psr, ssr);
                }
                isr &= ~(MASK_16|MASK_17);
        }
@@ -306,6 +300,7 @@ static irqreturn_t interrupt_hw(int irq, void *dev_id)
                ERR(("disabling interrupt source(s)!\n"));
                SAA7146_IER_DISABLE(dev,isr);
        }
+       saa7146_write(dev, ISR, ack_isr);
        return IRQ_HANDLED;
 }
 
index f823286341ebd29d327fee76d122aecfd9a3cf3e..7e7689afae629c0a012979dc56a2dc6f30ade7d3 100644 (file)
@@ -202,7 +202,8 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
                                /* a signal arrived */
                                return -ERESTARTSYS;
 
-                       printk(KERN_WARNING "saa7146_i2c_writeout: timed out waiting for end of xfer\n");
+                       printk(KERN_WARNING "%s %s [irq]: timed out waiting for end of xfer\n",
+                               dev->name, __FUNCTION__);
                        return -EIO;
                }
                status = saa7146_read(dev, I2C_STATUS);
@@ -219,7 +220,8 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
                                break;
                        }
                        if (time_after(jiffies,timeout)) {
-                               printk(KERN_WARNING "saa7146_i2c_writeout: timed out waiting for MC2\n");
+                               printk(KERN_WARNING "%s %s: timed out waiting for MC2\n",
+                                       dev->name, __FUNCTION__);
                                return -EIO;
                        }
                }
@@ -235,7 +237,8 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
                                /* this is normal when probing the bus
                                 * (no answer from nonexisistant device...)
                                 */
-                               DEB_I2C(("saa7146_i2c_writeout: timed out waiting for end of xfer\n"));
+                               printk(KERN_WARNING "%s %s [poll]: timed out waiting for end of xfer\n",
+                                       dev->name, __FUNCTION__);
                                return -EIO;
                        }
                        if (++trial < 50 && short_delay)
@@ -246,8 +249,16 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
        }
 
        /* give a detailed status report */
-       if ( 0 != (status & SAA7146_I2C_ERR)) {
-
+       if ( 0 != (status & (SAA7146_I2C_SPERR | SAA7146_I2C_APERR |
+                            SAA7146_I2C_DTERR | SAA7146_I2C_DRERR |
+                            SAA7146_I2C_AL    | SAA7146_I2C_ERR   |
+                            SAA7146_I2C_BUSY)) ) {
+
+               if ( 0 == (status & SAA7146_I2C_ERR) ||
+                    0 == (status & SAA7146_I2C_BUSY) ) {
+                       /* it may take some time until ERR goes high - ignore */
+                       DEB_I2C(("unexpected i2c status %04x\n", status));
+               }
                if( 0 != (status & SAA7146_I2C_SPERR) ) {
                        DEB_I2C(("error due to invalid start/stop condition.\n"));
                }