e9hack wrote:
> Manfred Petz wrote:
> > actually, both patches help. no more timeouts, and the frontend drivers
> > get loaded correctly (tried each patch separately). tried with latest hg
> > & 2.6.22.
>
> I don't understand why both patches do solve the timeout problem. The message
> 'timed out waiting for
> end of xfer' means, that no i2c-interrupt was delivered. In this case, the
> return value of
> saa7146_i2c_writeout() is -EIO. The first patch has only an effect, if the
> return value is
> -EREMOTEIO. The second patch reduces the i2c bit-rate. Usually, it has
> nothing to do with the
> interrupts.
A lower i2c bit rate might have changed the timing.
> Independently of this, I've found some strange things. The drivers for the
> TT-C2300 and the Cinergy
> DVB-C cards probe some i2c devices which don't exist. This results in an
> address error (missing ACK
> after the device address). I see three interrupts for this error. The first
> sets I2C_BUSY and
> I2C_APERR within I2C_STATUS. It does not wake-up the waiting thread and may
> print the message
> 'unhandled irq: i2c'. The second interrupt is the normal error interrupt
> which does wake-up the
> thread. I2C_BUSSY, I2C_ERR and I2C_APERR are set. The third interrupt has set
> the same three status
> bits. It may print the message 'unexpected irq: i2c', because the thread was
> already wake-up. If the
> chip-set is only able to deliver the first interrupt, the error interrupt
> will be never delivered
> and the timeout occurs.
Imho the interrupt processing was broken:
- The first I2C interrupt should be used to wake-up the task.
It does not matter that it takes some time until ERR in IIC_STA
will be updated. We don't need it.
- Interrupts must be acknowledged at the end of the ISR.
@all
Please test the attached patch.
There shouldn't be any unexpected I2C interrupts anymore.
CU
Oliver
--
----------------------------------------------------------------
VDR Remote Plugin 0.3.9: http://www.escape-edv.de/endriss/vdr/
----------------------------------------------------------------
diff -r 0f9dfb292f40 linux/drivers/media/common/saa7146_core.c
--- a/linux/drivers/media/common/saa7146_core.c Tue Jul 17 02:27:12 2007 +0200
+++ b/linux/drivers/media/common/saa7146_core.c Tue Jul 17 04:17:36 2007 +0200
@@ -252,18 +252,17 @@ static irqreturn_t interrupt_hw(int irq,
#endif
{
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 ) {
/* nope, some other device */
return IRQ_NONE;
}
-
- saa7146_write(dev, ISR, isr);
if( 0 != (dev->ext)) {
if( 0 != (dev->ext->irq_mask & isr )) {
@@ -287,21 +286,16 @@ static irqreturn_t interrupt_hw(int irq,
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 "saa7146: unexpected i2c irq: isr %08x psr %08x ssr %08x\n",
+ isr, psr, ssr);
}
isr &= ~(MASK_16|MASK_17);
}
@@ -310,6 +304,7 @@ static irqreturn_t interrupt_hw(int irq,
ERR(("disabling interrupt source(s)!\n"));
SAA7146_IER_DISABLE(dev,isr);
}
+ saa7146_write(dev, ISR, ack_isr);
return IRQ_HANDLED;
}
_______________________________________________
linux-dvb mailing list
[email protected]
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb