mirror of
https://github.com/torvalds/linux.git
synced 2024-11-16 00:52:01 +00:00
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: Andy Walls <awalls@radix.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
8711615951
commit
5f0a3cfcfd
@ -478,9 +478,10 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
|
||||
u32 __iomem *xpu_state;
|
||||
wait_queue_head_t *waitq;
|
||||
struct mutex *mb_lock;
|
||||
long int timeout, ret;
|
||||
unsigned long int t0, timeout, ret;
|
||||
int i;
|
||||
char argstr[MAX_MB_ARGUMENTS*11+1];
|
||||
DEFINE_WAIT(w);
|
||||
|
||||
if (info == NULL) {
|
||||
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[])
|
||||
|
||||
CX18_DEBUG_HI_IRQ("sending interrupt SW1: %x to send %s\n",
|
||||
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);
|
||||
|
||||
ret = wait_event_timeout(
|
||||
*waitq,
|
||||
cx18_readl(cx, &mb->ack) == cx18_readl(cx, &mb->request),
|
||||
timeout);
|
||||
t0 = jiffies;
|
||||
ack = cx18_readl(cx, &mb->ack);
|
||||
if (ack != req) {
|
||||
schedule_timeout(timeout);
|
||||
ret = jiffies - t0;
|
||||
ack = cx18_readl(cx, &mb->ack);
|
||||
} else {
|
||||
ret = jiffies - t0;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Timed out */
|
||||
finish_wait(waitq, &w);
|
||||
|
||||
if (req != ack) {
|
||||
mutex_unlock(mb_lock);
|
||||
CX18_DEBUG_WARN("sending %s timed out waiting %d msecs for RPU "
|
||||
"acknowledgement\n",
|
||||
info->name, jiffies_to_msecs(timeout));
|
||||
if (ret >= timeout) {
|
||||
/* Timed out */
|
||||
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;
|
||||
}
|
||||
|
||||
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",
|
||||
jiffies_to_msecs(timeout-ret), info->name);
|
||||
jiffies_to_msecs(ret), info->name);
|
||||
|
||||
/* Collect data returned by the XPU */
|
||||
for (i = 0; i < MAX_MB_ARGUMENTS; i++)
|
||||
|
Loading…
Reference in New Issue
Block a user