diff options
| -rw-r--r-- | drivers/media/video/vivi.c | 73 |
1 files changed, 41 insertions, 32 deletions
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 004209d54498..c9d23633fe42 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c | |||
| @@ -425,48 +425,57 @@ static void vivi_thread_tick(struct vivi_dmaqueue *dma_q) | |||
| 425 | spin_unlock(&dev->slock); | 425 | spin_unlock(&dev->slock); |
| 426 | } | 426 | } |
| 427 | 427 | ||
| 428 | #define frames_to_ms(frames) \ | ||
| 429 | ((frames * WAKE_NUMERATOR * 1000) / WAKE_DENOMINATOR) | ||
| 430 | |||
| 428 | static void vivi_sleep(struct vivi_dmaqueue *dma_q) | 431 | static void vivi_sleep(struct vivi_dmaqueue *dma_q) |
| 429 | { | 432 | { |
| 430 | struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq); | 433 | struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq); |
| 431 | int timeout; | 434 | int timeout, running_time; |
| 432 | DECLARE_WAITQUEUE(wait, current); | 435 | DECLARE_WAITQUEUE(wait, current); |
| 433 | 436 | ||
| 434 | dprintk(dev, 1, "%s dma_q=0x%08lx\n", __FUNCTION__, | 437 | dprintk(dev, 1, "%s dma_q=0x%08lx\n", __FUNCTION__, |
| 435 | (unsigned long)dma_q); | 438 | (unsigned long)dma_q); |
| 436 | 439 | ||
| 437 | add_wait_queue(&dma_q->wq, &wait); | 440 | add_wait_queue(&dma_q->wq, &wait); |
| 438 | if (!kthread_should_stop()) { | 441 | if (kthread_should_stop()) |
| 439 | dma_q->frame++; | 442 | goto stop_task; |
| 440 | 443 | ||
| 441 | /* Calculate time to wake up */ | 444 | running_time = jiffies - dma_q->ini_jiffies; |
| 442 | timeout = dma_q->ini_jiffies+ | 445 | dma_q->frame++; |
| 443 | msecs_to_jiffies((dma_q->frame*WAKE_NUMERATOR * 1000) | 446 | |
| 444 | / WAKE_DENOMINATOR) - jiffies; | 447 | /* Calculate time to wake up */ |
| 445 | 448 | timeout = msecs_to_jiffies(frames_to_ms(dma_q->frame)) - running_time; | |
| 446 | if (timeout <= 0) { | 449 | |
| 447 | int old = dma_q->frame; | 450 | if (timeout > msecs_to_jiffies(frames_to_ms(2)) || timeout <= 0) { |
| 448 | dma_q->frame = (jiffies_to_msecs(jiffies - | 451 | int old = dma_q->frame; |
| 449 | dma_q->ini_jiffies) * | 452 | int nframes; |
| 450 | WAKE_DENOMINATOR) / | 453 | |
| 451 | (WAKE_NUMERATOR * 1000) + 1; | 454 | dma_q->frame = (jiffies_to_msecs(running_time) / |
| 452 | 455 | frames_to_ms(1)) + 1; | |
| 453 | timeout = dma_q->ini_jiffies+ | 456 | |
| 454 | msecs_to_jiffies((dma_q->frame * | 457 | timeout = msecs_to_jiffies(frames_to_ms(dma_q->frame)) |
| 455 | WAKE_NUMERATOR * 1000) | 458 | - running_time; |
| 456 | / WAKE_DENOMINATOR) - jiffies; | 459 | |
| 457 | 460 | if (unlikely (timeout <= 0)) | |
| 458 | dprintk(dev, 1, "underrun, losed %d frames. " | 461 | timeout = 1; |
| 459 | "Now, frame is %d. Waking on %d jiffies\n", | 462 | |
| 460 | dma_q->frame-old, dma_q->frame, timeout); | 463 | nframes = (dma_q->frame > old)? |
| 461 | } else | 464 | dma_q->frame - old : old - dma_q->frame; |
| 462 | dprintk(dev, 1, "will sleep for %i jiffies\n", | 465 | |
| 463 | timeout); | 466 | dprintk(dev, 1, "%ld: %s %d frames. " |
| 464 | 467 | "Current frame is %d. Will sleep for %d jiffies\n", | |
| 465 | vivi_thread_tick(dma_q); | 468 | jiffies, |
| 466 | 469 | (dma_q->frame > old)? "Underrun, losed" : "Overrun of", | |
| 467 | schedule_timeout_interruptible(timeout); | 470 | nframes, dma_q->frame, timeout); |
| 468 | } | 471 | } else |
| 472 | dprintk(dev, 1, "will sleep for %d jiffies\n", timeout); | ||
| 473 | |||
| 474 | vivi_thread_tick(dma_q); | ||
| 475 | |||
| 476 | schedule_timeout_interruptible(timeout); | ||
| 469 | 477 | ||
| 478 | stop_task: | ||
| 470 | remove_wait_queue(&dma_q->wq, &wait); | 479 | remove_wait_queue(&dma_q->wq, &wait); |
| 471 | try_to_freeze(); | 480 | try_to_freeze(); |
| 472 | } | 481 | } |
