Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[linux-dvb] Fix to the jerking problem with tda10045h



Hi, the jerking was caused by the i2c busyloop delays chewing too much CPU. 
The attached patch should fix it. 

Basically, I've made the i2c code use the busy-waiting-low-latency 
mdelay()/my_delay() combination if there is lots of data being transferred. 
Otherwise it just uses the high latency my_delay() code as previously.

Now for some soak testing.
Index: linux/drivers/media/common/saa7146_i2c.c
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/common/saa7146_i2c.c,v
retrieving revision 1.19
diff -u -p -r1.19 saa7146_i2c.c
--- linux/drivers/media/common/saa7146_i2c.c	14 Jun 2003 20:06:03 -0000	1.19
+++ linux/drivers/media/common/saa7146_i2c.c	16 Jun 2003 10:37:18 -0000
@@ -187,7 +187,7 @@ int saa7146_i2c_reset(struct saa7146_dev
    it returns 0 if ok, -1 if the transfer failed, -2 if the transfer
    failed badly (e.g. address error) */
 static
-int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword)
+int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_delay)
 {
 	u32 status = 0, mc2 = 0;
 	int trial = 0;
@@ -245,7 +245,7 @@ int saa7146_i2c_writeout(struct saa7146_
 				DEB_I2C(("saa7146_i2c_writeout: timed out waiting for end of xfer\n"));
 				return -EIO;
 			}
-			if (++trial < 10)
+			if ((++trial < 20) && short_delay)
 				udelay(10);
 			else
 				my_wait(dev,1);
@@ -290,6 +290,7 @@ int saa7146_i2c_transfer(struct saa7146_
 	u32* buffer = dev->d_i2c.cpu_addr;
 	int err = 0;
         int address_err = 0;
+        int short_delay = 0;
 	
 	if (down_interruptible (&dev->i2c_lock))
 		return -ERESTARTSYS;
@@ -305,6 +306,8 @@ int saa7146_i2c_transfer(struct saa7146_
 		goto out;
 	}
 
+        if (count > 3) short_delay = 1;
+  
 	do {
 		/* reset the i2c-device if necessary */
 		err = saa7146_i2c_reset(dev);
@@ -315,7 +318,7 @@ int saa7146_i2c_transfer(struct saa7146_
 
 		/* write out the u32s one after another */
 		for(i = 0; i < count; i++) {
-			err = saa7146_i2c_writeout(dev, &buffer[i] );
+			err = saa7146_i2c_writeout(dev, &buffer[i], short_delay);
 			if ( 0 != err) {
 				/* this one is unsatisfying: some i2c slaves on some
 				   dvb cards don't acknowledge correctly, so the saa7146
@@ -370,7 +373,7 @@ out:
 	if( 0 == dev->revision ) {
 		u32 zero = 0;
 		saa7146_i2c_reset(dev);
-		if( 0 != saa7146_i2c_writeout(dev, &zero)) {
+		if( 0 != saa7146_i2c_writeout(dev, &zero, short_delay)) {
 			INFO(("revision 0 error. this should never happen.\n"));
 		}
 	}

Home | Main Index | Thread Index