diff options
Diffstat (limited to 'drivers/media')
-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 | } |