aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/cx18/cx18-driver.c2
-rw-r--r--drivers/media/video/cx18/cx18-driver.h7
-rw-r--r--drivers/media/video/cx18/cx18-io.c4
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c47
4 files changed, 42 insertions, 18 deletions
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 3079e466e6e7..8ef11d578b8d 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -187,7 +187,7 @@ MODULE_VERSION(CX18_VERSION);
187/* Generic utility functions */ 187/* Generic utility functions */
188int cx18_msleep_timeout(unsigned int msecs, int intr) 188int cx18_msleep_timeout(unsigned int msecs, int intr)
189{ 189{
190 int timeout = msecs_to_jiffies(msecs); 190 long int timeout = msecs_to_jiffies(msecs);
191 int sig; 191 int sig;
192 192
193 do { 193 do {
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index e2ec15549783..ce76806759ec 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -360,6 +360,12 @@ struct cx18_mmio_stats {
360 atomic_t retried_read[CX18_MAX_MMIO_RD_RETRIES+1]; 360 atomic_t retried_read[CX18_MAX_MMIO_RD_RETRIES+1];
361}; 361};
362 362
363#define CX18_MAX_MB_ACK_DELAY 100
364
365struct cx18_mbox_stats {
366 atomic_t mb_ack_delay[CX18_MAX_MB_ACK_DELAY+1];
367};
368
363/* Struct to hold info about cx18 cards */ 369/* Struct to hold info about cx18 cards */
364struct cx18 { 370struct cx18 {
365 int num; /* board number, -1 during init! */ 371 int num; /* board number, -1 during init! */
@@ -452,6 +458,7 @@ struct cx18 {
452 458
453 /* Statistics */ 459 /* Statistics */
454 struct cx18_mmio_stats mmio_stats; 460 struct cx18_mmio_stats mmio_stats;
461 struct cx18_mbox_stats mbox_stats;
455 462
456 /* v4l2 and User settings */ 463 /* v4l2 and User settings */
457 464
diff --git a/drivers/media/video/cx18/cx18-io.c b/drivers/media/video/cx18/cx18-io.c
index 0ad8dea3e600..48a8adc83c2f 100644
--- a/drivers/media/video/cx18/cx18-io.c
+++ b/drivers/media/video/cx18/cx18-io.c
@@ -37,6 +37,10 @@ void cx18_log_statistics(struct cx18 *cx)
37 for (i = 0; i <= CX18_MAX_MMIO_RD_RETRIES; i++) 37 for (i = 0; i <= CX18_MAX_MMIO_RD_RETRIES; i++)
38 CX18_DEBUG_INFO("retried_read[%d] = %d\n", i, 38 CX18_DEBUG_INFO("retried_read[%d] = %d\n", i,
39 atomic_read(&cx->mmio_stats.retried_read[i])); 39 atomic_read(&cx->mmio_stats.retried_read[i]));
40 for (i = 0; i <= CX18_MAX_MB_ACK_DELAY; i++)
41 if (atomic_read(&cx->mbox_stats.mb_ack_delay[i]))
42 CX18_DEBUG_INFO("mb_ack_delay[%d] = %d\n", i,
43 atomic_read(&cx->mbox_stats.mb_ack_delay[i]));
40 return; 44 return;
41} 45}
42 46
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index 0de4b9a7bbca..35f7188d4d3b 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -118,6 +118,12 @@ long cx18_mb_ack(struct cx18 *cx, const struct cx18_mailbox *mb, int rpu)
118 return 0; 118 return 0;
119} 119}
120 120
121static void cx18_api_log_ack_delay(struct cx18 *cx, int msecs)
122{
123 if (msecs > CX18_MAX_MB_ACK_DELAY)
124 msecs = CX18_MAX_MB_ACK_DELAY;
125 atomic_inc(&cx->mbox_stats.mb_ack_delay[msecs]);
126}
121 127
122static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[]) 128static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
123{ 129{
@@ -127,8 +133,7 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
127 u32 __iomem *xpu_state; 133 u32 __iomem *xpu_state;
128 wait_queue_head_t *waitq; 134 wait_queue_head_t *waitq;
129 struct mutex *mb_lock; 135 struct mutex *mb_lock;
130 int timeout = 100; 136 long int timeout, ret;
131 long unsigned int j, ret;
132 int i; 137 int i;
133 138
134 if (info == NULL) { 139 if (info == NULL) {
@@ -176,18 +181,18 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
176 */ 181 */
177 state = cx18_readl(cx, xpu_state); 182 state = cx18_readl(cx, xpu_state);
178 req = cx18_readl(cx, &mb->request); 183 req = cx18_readl(cx, &mb->request);
179 j = msecs_to_jiffies(timeout); 184 timeout = msecs_to_jiffies(20); /* 1 field at 50 Hz vertical refresh */
180 ret = wait_event_timeout(*waitq, 185 ret = wait_event_timeout(*waitq,
181 (ack = cx18_readl(cx, &mb->ack)) == req, 186 (ack = cx18_readl(cx, &mb->ack)) == req,
182 j); 187 timeout);
183 if (req != ack) { 188 if (req != ack) {
184 /* waited long enough, make the mbox "not busy" from our end */ 189 /* waited long enough, make the mbox "not busy" from our end */
185 cx18_writel(cx, req, &mb->ack); 190 cx18_writel(cx, req, &mb->ack);
186 CX18_ERR("mbox was found stuck busy when setting up for %s; " 191 CX18_ERR("mbox was found stuck busy when setting up for %s; "
187 "clearing busy and trying to proceed\n", info->name); 192 "clearing busy and trying to proceed\n", info->name);
188 } else if (ret != j) 193 } else if (ret != timeout)
189 CX18_DEBUG_API("waited %u usecs for busy mbox to be acked\n", 194 CX18_DEBUG_API("waited %u usecs for busy mbox to be acked\n",
190 jiffies_to_usecs(j-ret)); 195 jiffies_to_usecs(timeout-ret));
191 196
192 /* Build the outgoing mailbox */ 197 /* Build the outgoing mailbox */
193 req = ((req & 0xfffffffe) == 0xfffffffe) ? 1 : req + 1; 198 req = ((req & 0xfffffffe) == 0xfffffffe) ? 1 : req + 1;
@@ -199,24 +204,28 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
199 cx18_writel(cx, req, &mb->request); 204 cx18_writel(cx, req, &mb->request);
200 cx18_writel(cx, req - 1, &mb->ack); /* ensure ack & req are distinct */ 205 cx18_writel(cx, req - 1, &mb->ack); /* ensure ack & req are distinct */
201 206
202 /* Notify the XPU and wait for it to send an Ack back */ 207 /*
203 if (info->flags & API_FAST) 208 * Notify the XPU and wait for it to send an Ack back
204 timeout /= 2; 209 * 21 ms = ~ 0.5 frames at a frame rate of 24 fps
205 j = msecs_to_jiffies(timeout); 210 * 42 ms = ~ 1 frame at a frame rate of 24 fps
211 */
212 timeout = msecs_to_jiffies((info->flags & API_FAST) ? 21 : 42);
206 213
207 CX18_DEBUG_HI_IRQ("sending interrupt SW1: %x to send %s\n", 214 CX18_DEBUG_HI_IRQ("sending interrupt SW1: %x to send %s\n",
208 irq, info->name); 215 irq, info->name);
209 cx18_write_reg_expect(cx, irq, SW1_INT_SET, irq, irq); 216 cx18_write_reg_expect(cx, irq, SW1_INT_SET, irq, irq);
210 217
211 ret = wait_event_interruptible_timeout( 218 ret = wait_event_timeout(
212 *waitq, 219 *waitq,
213 cx18_readl(cx, &mb->ack) == cx18_readl(cx, &mb->request), 220 cx18_readl(cx, &mb->ack) == cx18_readl(cx, &mb->request),
214 j); 221 timeout);
215 if (ret == 0) { 222 if (ret == 0) {
216 /* Timed out */ 223 /* Timed out */
217 mutex_unlock(mb_lock); 224 mutex_unlock(mb_lock);
218 CX18_ERR("sending %s timed out waiting for RPU " 225 i = jiffies_to_msecs(timeout);
219 "acknowledgement\n", info->name); 226 cx18_api_log_ack_delay(cx, i);
227 CX18_WARN("sending %s timed out waiting %d msecs for RPU "
228 "acknowledgement\n", info->name, i);
220 return -EINVAL; 229 return -EINVAL;
221 } else if (ret < 0) { 230 } else if (ret < 0) {
222 /* Interrupted */ 231 /* Interrupted */
@@ -224,9 +233,13 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
224 CX18_WARN("sending %s was interrupted waiting for RPU" 233 CX18_WARN("sending %s was interrupted waiting for RPU"
225 "acknowledgement\n", info->name); 234 "acknowledgement\n", info->name);
226 return -EINTR; 235 return -EINTR;
227 } else if (ret != j) 236 }
228 CX18_DEBUG_HI_API("waited %u usecs for %s to be acked\n", 237
229 jiffies_to_usecs(j-ret), info->name); 238 i = jiffies_to_msecs(timeout-ret);
239 cx18_api_log_ack_delay(cx, i);
240 if (ret != timeout)
241 CX18_DEBUG_HI_API("waited %u msecs for %s to be acked\n",
242 i, info->name);
230 243
231 /* Collect data returned by the XPU */ 244 /* Collect data returned by the XPU */
232 for (i = 0; i < MAX_MB_ARGUMENTS; i++) 245 for (i = 0; i < MAX_MB_ARGUMENTS; i++)