aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cafe_ccic.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/cafe_ccic.c')
-rw-r--r--drivers/media/video/cafe_ccic.c35
1 files changed, 32 insertions, 3 deletions
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index c08f650df423..ef5361824f87 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,
356{ 356{
357 unsigned int rval; 357 unsigned int rval;
358 unsigned long flags; 358 unsigned long flags;
359 DEFINE_WAIT(the_wait);
359 360
360 spin_lock_irqsave(&cam->dev_lock, flags); 361 spin_lock_irqsave(&cam->dev_lock, flags);
361 rval = TWSIC0_EN | ((addr << TWSIC0_SID_SHIFT) & TWSIC0_SID); 362 rval = TWSIC0_EN | ((addr << TWSIC0_SID_SHIFT) & TWSIC0_SID);
@@ -369,10 +370,29 @@ static int cafe_smbus_write_data(struct cafe_camera *cam,
369 rval = value | ((command << TWSIC1_ADDR_SHIFT) & TWSIC1_ADDR); 370 rval = value | ((command << TWSIC1_ADDR_SHIFT) & TWSIC1_ADDR);
370 cafe_reg_write(cam, REG_TWSIC1, rval); 371 cafe_reg_write(cam, REG_TWSIC1, rval);
371 spin_unlock_irqrestore(&cam->dev_lock, flags); 372 spin_unlock_irqrestore(&cam->dev_lock, flags);
372 msleep(2); /* Required or things flake */
373 373
374 /*
375 * Time to wait for the write to complete. THIS IS A RACY
376 * WAY TO DO IT, but the sad fact is that reading the TWSIC1
377 * register too quickly after starting the operation sends
378 * the device into a place that may be kinder and better, but
379 * which is absolutely useless for controlling the sensor. In
380 * practice we have plenty of time to get into our sleep state
381 * before the interrupt hits, and the worst case is that we
382 * time out and then see that things completed, so this seems
383 * the best way for now.
384 */
385 do {
386 prepare_to_wait(&cam->smbus_wait, &the_wait,
387 TASK_UNINTERRUPTIBLE);
388 schedule_timeout(1); /* even 1 jiffy is too long */
389 finish_wait(&cam->smbus_wait, &the_wait);
390 } while (!cafe_smbus_write_done(cam));
391
392#ifdef IF_THE_CAFE_HARDWARE_WORKED_RIGHT
374 wait_event_timeout(cam->smbus_wait, cafe_smbus_write_done(cam), 393 wait_event_timeout(cam->smbus_wait, cafe_smbus_write_done(cam),
375 CAFE_SMBUS_TIMEOUT); 394 CAFE_SMBUS_TIMEOUT);
395#endif
376 spin_lock_irqsave(&cam->dev_lock, flags); 396 spin_lock_irqsave(&cam->dev_lock, flags);
377 rval = cafe_reg_read(cam, REG_TWSIC1); 397 rval = cafe_reg_read(cam, REG_TWSIC1);
378 spin_unlock_irqrestore(&cam->dev_lock, flags); 398 spin_unlock_irqrestore(&cam->dev_lock, flags);
@@ -710,7 +730,7 @@ static void cafe_ctlr_init(struct cafe_camera *cam)
710 * Here we must wait a bit for the controller to come around. 730 * Here we must wait a bit for the controller to come around.
711 */ 731 */
712 spin_unlock_irqrestore(&cam->dev_lock, flags); 732 spin_unlock_irqrestore(&cam->dev_lock, flags);
713 mdelay(5); /* FIXME revisit this */ 733 msleep(5);
714 spin_lock_irqsave(&cam->dev_lock, flags); 734 spin_lock_irqsave(&cam->dev_lock, flags);
715 735
716 cafe_reg_write(cam, REG_GL_CSR, GCSR_CCIC_EN|GCSR_SRC|GCSR_MRC); 736 cafe_reg_write(cam, REG_GL_CSR, GCSR_CCIC_EN|GCSR_SRC|GCSR_MRC);
@@ -2233,12 +2253,21 @@ static int cafe_pci_resume(struct pci_dev *pdev)
2233 if (ret) 2253 if (ret)
2234 return ret; 2254 return ret;
2235 ret = pci_enable_device(pdev); 2255 ret = pci_enable_device(pdev);
2256
2236 if (ret) { 2257 if (ret) {
2237 cam_warn(cam, "Unable to re-enable device on resume!\n"); 2258 cam_warn(cam, "Unable to re-enable device on resume!\n");
2238 return ret; 2259 return ret;
2239 } 2260 }
2240 cafe_ctlr_init(cam); 2261 cafe_ctlr_init(cam);
2241 cafe_ctlr_power_up(cam); 2262 cafe_ctlr_power_down(cam);
2263
2264 mutex_lock(&cam->s_mutex);
2265 if (cam->users > 0) {
2266 cafe_ctlr_power_up(cam);
2267 __cafe_cam_reset(cam);
2268 }
2269 mutex_unlock(&cam->s_mutex);
2270
2242 set_bit(CF_CONFIG_NEEDED, &cam->flags); 2271 set_bit(CF_CONFIG_NEEDED, &cam->flags);
2243 if (cam->state == S_SPECREAD) 2272 if (cam->state == S_SPECREAD)
2244 cam->state = S_IDLE; /* Don't bother restarting */ 2273 cam->state = S_IDLE; /* Don't bother restarting */