Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=6d77444aca298b43a88086be446f943cd0442ef7
Commit:     6d77444aca298b43a88086be446f943cd0442ef7
Parent:     01659f2a0067d855089811529fa596cbc40f1e75
Author:     Jonathan Corbet <[EMAIL PROTECTED]>
AuthorDate: Fri Aug 17 01:02:33 2007 -0300
Committer:  Mauro Carvalho Chehab <[EMAIL PROTECTED]>
CommitDate: Mon Aug 20 12:18:04 2007 -0300

    V4L/DVB (6027): Get rid of an ill-behaved msleep in i2c write
    
    Configuring the OLPC camera requires something over 150 register
    writes.  Unfortunately, querying the CAFE i2c controller too
    soon after a write causes the hardware to flake.  The problem had
    been "solved" with an msleep() call, but, between the number of
    registers and how msleep() behaves, that resulted in a 3-second
    delay on camera initialization.  Instead, we hand-code a wait for
    the completion interrupt which avoids reading the status registers.
    
    Signed-off-by: Jonathan Corbet <[EMAIL PROTECTED]>
    Signed-off-by: Mauro Carvalho Chehab <[EMAIL PROTECTED]>
---
 drivers/media/video/cafe_ccic.c |   22 +++++++++++++++++++++-
 drivers/media/video/ov7670.c    |    5 ++++-
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index 8809010..acf64b1 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -356,6 +356,7 @@ static int cafe_smbus_write_data(struct cafe_camera *cam,
 {
        unsigned int rval;
        unsigned long flags;
+       DEFINE_WAIT(the_wait);
 
        spin_lock_irqsave(&cam->dev_lock, flags);
        rval = TWSIC0_EN | ((addr << TWSIC0_SID_SHIFT) & TWSIC0_SID);
@@ -369,10 +370,29 @@ static int cafe_smbus_write_data(struct cafe_camera *cam,
        rval = value | ((command << TWSIC1_ADDR_SHIFT) & TWSIC1_ADDR);
        cafe_reg_write(cam, REG_TWSIC1, rval);
        spin_unlock_irqrestore(&cam->dev_lock, flags);
-       msleep(2); /* Required or things flake */
 
+       /*
+        * Time to wait for the write to complete.  THIS IS A RACY
+        * WAY TO DO IT, but the sad fact is that reading the TWSIC1
+        * register too quickly after starting the operation sends
+        * the device into a place that may be kinder and better, but
+        * which is absolutely useless for controlling the sensor.  In
+        * practice we have plenty of time to get into our sleep state
+        * before the interrupt hits, and the worst case is that we
+        * time out and then see that things completed, so this seems
+        * the best way for now.
+        */
+       do {
+               prepare_to_wait(&cam->smbus_wait, &the_wait,
+                               TASK_UNINTERRUPTIBLE);
+               schedule_timeout(1); /* even 1 jiffy is too long */
+               finish_wait(&cam->smbus_wait, &the_wait);
+       } while (!cafe_smbus_write_done(cam));
+
+#ifdef IF_THE_CAFE_HARDWARE_WORKED_RIGHT
        wait_event_timeout(cam->smbus_wait, cafe_smbus_write_done(cam),
                        CAFE_SMBUS_TIMEOUT);
+#endif
        spin_lock_irqsave(&cam->dev_lock, flags);
        rval = cafe_reg_read(cam, REG_TWSIC1);
        spin_unlock_irqrestore(&cam->dev_lock, flags);
diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c
index f8f21dd..c4c5bd6 100644
--- a/drivers/media/video/ov7670.c
+++ b/drivers/media/video/ov7670.c
@@ -416,7 +416,10 @@ static int ov7670_read(struct i2c_client *c, unsigned char 
reg,
 static int ov7670_write(struct i2c_client *c, unsigned char reg,
                unsigned char value)
 {
-       return i2c_smbus_write_byte_data(c, reg, value);
+       int ret = i2c_smbus_write_byte_data(c, reg, value);
+       if (reg == REG_COM7 && (value & COM7_RESET))
+               msleep(2);  /* Wait for reset to run */
+       return ret;
 }
 
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to