aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c49
1 files changed, 37 insertions, 12 deletions
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index 2a4d4356d1b..df7d61d0a13 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -478,9 +478,10 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
478 u32 __iomem *xpu_state; 478 u32 __iomem *xpu_state;
479 wait_queue_head_t *waitq; 479 wait_queue_head_t *waitq;
480 struct mutex *mb_lock; 480 struct mutex *mb_lock;
481 long int timeout, ret; 481 unsigned long int t0, timeout, ret;
482 int i; 482 int i;
483 char argstr[MAX_MB_ARGUMENTS*11+1]; 483 char argstr[MAX_MB_ARGUMENTS*11+1];
484 DEFINE_WAIT(w);
484 485
485 if (info == NULL) { 486 if (info == NULL) {
486 CX18_WARN("unknown cmd %x\n", cmd); 487 CX18_WARN("unknown cmd %x\n", cmd);
@@ -562,25 +563,49 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
562 563
563 CX18_DEBUG_HI_IRQ("sending interrupt SW1: %x to send %s\n", 564 CX18_DEBUG_HI_IRQ("sending interrupt SW1: %x to send %s\n",
564 irq, info->name); 565 irq, info->name);
566
567 /* So we don't miss the wakeup, prepare to wait before notifying fw */
568 prepare_to_wait(waitq, &w, TASK_UNINTERRUPTIBLE);
565 cx18_write_reg_expect(cx, irq, SW1_INT_SET, irq, irq); 569 cx18_write_reg_expect(cx, irq, SW1_INT_SET, irq, irq);
566 570
567 ret = wait_event_timeout( 571 t0 = jiffies;
568 *waitq, 572 ack = cx18_readl(cx, &mb->ack);
569 cx18_readl(cx, &mb->ack) == cx18_readl(cx, &mb->request), 573 if (ack != req) {
570 timeout); 574 schedule_timeout(timeout);
575 ret = jiffies - t0;
576 ack = cx18_readl(cx, &mb->ack);
577 } else {
578 ret = jiffies - t0;
579 }
580
581 finish_wait(waitq, &w);
571 582
572 if (ret == 0) { 583 if (req != ack) {
573 /* Timed out */
574 mutex_unlock(mb_lock); 584 mutex_unlock(mb_lock);
575 CX18_DEBUG_WARN("sending %s timed out waiting %d msecs for RPU " 585 if (ret >= timeout) {
576 "acknowledgement\n", 586 /* Timed out */
577 info->name, jiffies_to_msecs(timeout)); 587 CX18_DEBUG_WARN("sending %s timed out waiting %d msecs "
588 "for RPU acknowledgement\n",
589 info->name, jiffies_to_msecs(ret));
590 } else {
591 CX18_DEBUG_WARN("woken up before mailbox ack was ready "
592 "after submitting %s to RPU. only "
593 "waited %d msecs on req %u but awakened"
594 " with unmatched ack %u\n",
595 info->name,
596 jiffies_to_msecs(ret),
597 req, ack);
598 }
578 return -EINVAL; 599 return -EINVAL;
579 } 600 }
580 601
581 if (ret != timeout) 602 if (ret >= timeout)
603 CX18_DEBUG_WARN("failed to be awakened upon RPU acknowledgment "
604 "sending %s; timed out waiting %d msecs\n",
605 info->name, jiffies_to_msecs(ret));
606 else
582 CX18_DEBUG_HI_API("waited %u msecs for %s to be acked\n", 607 CX18_DEBUG_HI_API("waited %u msecs for %s to be acked\n",
583 jiffies_to_msecs(timeout-ret), info->name); 608 jiffies_to_msecs(ret), info->name);
584 609
585 /* Collect data returned by the XPU */ 610 /* Collect data returned by the XPU */
586 for (i = 0; i < MAX_MB_ARGUMENTS; i++) 611 for (i = 0; i < MAX_MB_ARGUMENTS; i++)