Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 124283
b: refs/heads/master
c: 330c6ec
h: refs/heads/master
i:
  124281: f8d3a95
  124279: 8e4ac67
v: v3
  • Loading branch information
Andy Walls authored and Mauro Carvalho Chehab committed Dec 30, 2008
1 parent f8de778 commit 69c5373
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 19 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ac50441720332f22a9d85ac03151d6acb7bc55d6
refs/heads/master: 330c6ec8942765e81f237bd58020da1b161935ce
2 changes: 1 addition & 1 deletion trunk/drivers/media/video/cx18/cx18-driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ MODULE_VERSION(CX18_VERSION);
/* Generic utility functions */
int cx18_msleep_timeout(unsigned int msecs, int intr)
{
int timeout = msecs_to_jiffies(msecs);
long int timeout = msecs_to_jiffies(msecs);
int sig;

do {
Expand Down
7 changes: 7 additions & 0 deletions trunk/drivers/media/video/cx18/cx18-driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,12 @@ struct cx18_mmio_stats {
atomic_t retried_read[CX18_MAX_MMIO_RD_RETRIES+1];
};

#define CX18_MAX_MB_ACK_DELAY 100

struct cx18_mbox_stats {
atomic_t mb_ack_delay[CX18_MAX_MB_ACK_DELAY+1];
};

/* Struct to hold info about cx18 cards */
struct cx18 {
int num; /* board number, -1 during init! */
Expand Down Expand Up @@ -452,6 +458,7 @@ struct cx18 {

/* Statistics */
struct cx18_mmio_stats mmio_stats;
struct cx18_mbox_stats mbox_stats;

/* v4l2 and User settings */

Expand Down
4 changes: 4 additions & 0 deletions trunk/drivers/media/video/cx18/cx18-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ void cx18_log_statistics(struct cx18 *cx)
for (i = 0; i <= CX18_MAX_MMIO_RD_RETRIES; i++)
CX18_DEBUG_INFO("retried_read[%d] = %d\n", i,
atomic_read(&cx->mmio_stats.retried_read[i]));
for (i = 0; i <= CX18_MAX_MB_ACK_DELAY; i++)
if (atomic_read(&cx->mbox_stats.mb_ack_delay[i]))
CX18_DEBUG_INFO("mb_ack_delay[%d] = %d\n", i,
atomic_read(&cx->mbox_stats.mb_ack_delay[i]));
return;
}

Expand Down
47 changes: 30 additions & 17 deletions trunk/drivers/media/video/cx18/cx18-mailbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,12 @@ long cx18_mb_ack(struct cx18 *cx, const struct cx18_mailbox *mb, int rpu)
return 0;
}

static void cx18_api_log_ack_delay(struct cx18 *cx, int msecs)
{
if (msecs > CX18_MAX_MB_ACK_DELAY)
msecs = CX18_MAX_MB_ACK_DELAY;
atomic_inc(&cx->mbox_stats.mb_ack_delay[msecs]);
}

static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
{
Expand All @@ -127,8 +133,7 @@ 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;
int timeout = 100;
long unsigned int j, ret;
long int timeout, ret;
int i;

if (info == NULL) {
Expand Down Expand Up @@ -176,18 +181,18 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
*/
state = cx18_readl(cx, xpu_state);
req = cx18_readl(cx, &mb->request);
j = msecs_to_jiffies(timeout);
timeout = msecs_to_jiffies(20); /* 1 field at 50 Hz vertical refresh */
ret = wait_event_timeout(*waitq,
(ack = cx18_readl(cx, &mb->ack)) == req,
j);
timeout);
if (req != ack) {
/* waited long enough, make the mbox "not busy" from our end */
cx18_writel(cx, req, &mb->ack);
CX18_ERR("mbox was found stuck busy when setting up for %s; "
"clearing busy and trying to proceed\n", info->name);
} else if (ret != j)
} else if (ret != timeout)
CX18_DEBUG_API("waited %u usecs for busy mbox to be acked\n",
jiffies_to_usecs(j-ret));
jiffies_to_usecs(timeout-ret));

/* Build the outgoing mailbox */
req = ((req & 0xfffffffe) == 0xfffffffe) ? 1 : req + 1;
Expand All @@ -199,34 +204,42 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
cx18_writel(cx, req, &mb->request);
cx18_writel(cx, req - 1, &mb->ack); /* ensure ack & req are distinct */

/* Notify the XPU and wait for it to send an Ack back */
if (info->flags & API_FAST)
timeout /= 2;
j = msecs_to_jiffies(timeout);
/*
* Notify the XPU and wait for it to send an Ack back
* 21 ms = ~ 0.5 frames at a frame rate of 24 fps
* 42 ms = ~ 1 frame at a frame rate of 24 fps
*/
timeout = msecs_to_jiffies((info->flags & API_FAST) ? 21 : 42);

CX18_DEBUG_HI_IRQ("sending interrupt SW1: %x to send %s\n",
irq, info->name);
cx18_write_reg_expect(cx, irq, SW1_INT_SET, irq, irq);

ret = wait_event_interruptible_timeout(
ret = wait_event_timeout(
*waitq,
cx18_readl(cx, &mb->ack) == cx18_readl(cx, &mb->request),
j);
timeout);
if (ret == 0) {
/* Timed out */
mutex_unlock(mb_lock);
CX18_ERR("sending %s timed out waiting for RPU "
"acknowledgement\n", info->name);
i = jiffies_to_msecs(timeout);
cx18_api_log_ack_delay(cx, i);
CX18_WARN("sending %s timed out waiting %d msecs for RPU "
"acknowledgement\n", info->name, i);
return -EINVAL;
} else if (ret < 0) {
/* Interrupted */
mutex_unlock(mb_lock);
CX18_WARN("sending %s was interrupted waiting for RPU"
"acknowledgement\n", info->name);
return -EINTR;
} else if (ret != j)
CX18_DEBUG_HI_API("waited %u usecs for %s to be acked\n",
jiffies_to_usecs(j-ret), info->name);
}

i = jiffies_to_msecs(timeout-ret);
cx18_api_log_ack_delay(cx, i);
if (ret != timeout)
CX18_DEBUG_HI_API("waited %u msecs for %s to be acked\n",
i, info->name);

/* Collect data returned by the XPU */
for (i = 0; i < MAX_MB_ARGUMENTS; i++)
Expand Down

0 comments on commit 69c5373

Please sign in to comment.