Commit 5f0a3cfc authored by Andy Walls's avatar Andy Walls Committed by Mauro Carvalho Chehab

V4L/DVB (11617): cx18: Set up to wait for a one-shot response before sending a firmware cmd

When sending an outgoing firmware command, prepare to wait before we raise the
interrupt, so we don't miss the wake_up() on the acknowledgment.  When waiting
for the acknowledgement, there is no need to loop around schedule(), as there
will only be one interrupt, and hence one wake_up(), issued.
Signed-off-by: default avatarAndy Walls <awalls@radix.net>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 87116159
...@@ -478,9 +478,10 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[]) ...@@ -478,9 +478,10 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
u32 __iomem *xpu_state; u32 __iomem *xpu_state;
wait_queue_head_t *waitq; wait_queue_head_t *waitq;
struct mutex *mb_lock; struct mutex *mb_lock;
long int timeout, ret; unsigned long int t0, timeout, ret;
int i; int i;
char argstr[MAX_MB_ARGUMENTS*11+1]; char argstr[MAX_MB_ARGUMENTS*11+1];
DEFINE_WAIT(w);
if (info == NULL) { if (info == NULL) {
CX18_WARN("unknown cmd %x\n", cmd); 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,25 +563,49 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
CX18_DEBUG_HI_IRQ("sending interrupt SW1: %x to send %s\n", CX18_DEBUG_HI_IRQ("sending interrupt SW1: %x to send %s\n",
irq, info->name); irq, info->name);
/* So we don't miss the wakeup, prepare to wait before notifying fw */
prepare_to_wait(waitq, &w, TASK_UNINTERRUPTIBLE);
cx18_write_reg_expect(cx, irq, SW1_INT_SET, irq, irq); cx18_write_reg_expect(cx, irq, SW1_INT_SET, irq, irq);
ret = wait_event_timeout( t0 = jiffies;
*waitq, ack = cx18_readl(cx, &mb->ack);
cx18_readl(cx, &mb->ack) == cx18_readl(cx, &mb->request), if (ack != req) {
timeout); schedule_timeout(timeout);
ret = jiffies - t0;
ack = cx18_readl(cx, &mb->ack);
} else {
ret = jiffies - t0;
}
finish_wait(waitq, &w);
if (ret == 0) { if (req != ack) {
/* Timed out */
mutex_unlock(mb_lock); mutex_unlock(mb_lock);
CX18_DEBUG_WARN("sending %s timed out waiting %d msecs for RPU " if (ret >= timeout) {
"acknowledgement\n", /* Timed out */
info->name, jiffies_to_msecs(timeout)); CX18_DEBUG_WARN("sending %s timed out waiting %d msecs "
"for RPU acknowledgement\n",
info->name, jiffies_to_msecs(ret));
} else {
CX18_DEBUG_WARN("woken up before mailbox ack was ready "
"after submitting %s to RPU. only "
"waited %d msecs on req %u but awakened"
" with unmatched ack %u\n",
info->name,
jiffies_to_msecs(ret),
req, ack);
}
return -EINVAL; return -EINVAL;
} }
if (ret != timeout) if (ret >= timeout)
CX18_DEBUG_WARN("failed to be awakened upon RPU acknowledgment "
"sending %s; timed out waiting %d msecs\n",
info->name, jiffies_to_msecs(ret));
else
CX18_DEBUG_HI_API("waited %u msecs for %s to be acked\n", CX18_DEBUG_HI_API("waited %u msecs for %s to be acked\n",
jiffies_to_msecs(timeout-ret), info->name); jiffies_to_msecs(ret), info->name);
/* Collect data returned by the XPU */ /* Collect data returned by the XPU */
for (i = 0; i < MAX_MB_ARGUMENTS; i++) for (i = 0; i < MAX_MB_ARGUMENTS; i++)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment