V4L/DVB (12940): SAA7164: IRQ / message timeout related change
authorSteven Toth <stoth@kernellabs.com>
Wed, 12 Aug 2009 15:14:37 +0000 (12:14 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Sat, 19 Sep 2009 03:15:08 +0000 (00:15 -0300)
In some cases we're seeing large timeouts on commands. I'm changing the
implementation so that the deferred worker checks the PCI bus for
any messages and signals the waiting caller accordingly. The previous
mechanism was too unreliable.

Signed-off-by: Steven Toth <stoth@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/saa7164/saa7164-cmd.c
drivers/media/video/saa7164/saa7164-core.c
drivers/media/video/saa7164/saa7164.h

index cd3af4d4364f2020af46698d9314db934269a58d..e097f1a0969a26441a0aa1a02df5136aaf1d4460 100644 (file)
@@ -78,6 +78,43 @@ u32 saa7164_cmd_timeout_get(struct saa7164_dev *dev, u8 seqno)
        return ret;
 }
 
+/* Commands to the f/w get marshelled to/from this code then onto the PCI
+ * -bus/c running buffer. */
+int saa7164_irq_dequeue(struct saa7164_dev *dev)
+{
+       int ret = SAA_OK;
+       u32 timeout;
+       wait_queue_head_t *q = 0;
+       dprintk(DBGLVL_CMD, "%s()\n", __func__);
+
+       /* While any outstand message on the bus exists... */
+       do {
+
+               /* Peek the msg bus */
+               tmComResInfo_t tRsp = { 0, 0, 0, 0, 0, 0 };
+               ret = saa7164_bus_get(dev, &tRsp, NULL, 1);
+               if (ret != SAA_OK)
+                       break;
+
+               q = &dev->cmds[tRsp.seqno].wait;
+               timeout = saa7164_cmd_timeout_get(dev, tRsp.seqno);
+               dprintk(DBGLVL_CMD, "%s() timeout = %d\n", __func__, timeout);
+               if (!timeout) {
+                       dprintk(DBGLVL_CMD,
+                               "%s() signalled seqno(%d) (for dequeue)\n",
+                               __func__, tRsp.seqno);
+                       dev->cmds[tRsp.seqno].signalled = 1;
+                       wake_up(q);
+               } else {
+                       printk(KERN_ERR
+                               "%s() found timed out command on the bus\n",
+                                       __func__);
+               }
+       } while (0);
+
+       return ret;
+}
+
 /* Commands to the f/w get marshelled to/from this code then onto the PCI
  * -bus/c running buffer. */
 int saa7164_cmd_dequeue(struct saa7164_dev *dev)
index 3753b52e0294e2f4568e32b1071dd41e8bfd0c46..e878fbcbb1ebbe52c4fd3ba132b719318dafc71b 100644 (file)
@@ -69,7 +69,7 @@ static void saa7164_work_cmdhandler(struct work_struct *w)
        struct saa7164_dev *dev = container_of(w, struct saa7164_dev, workcmd);
 
        /* Wake up any complete commands */
-       saa7164_cmd_signal(dev, 0);
+       saa7164_irq_dequeue(dev);
 }
 
 static void saa7164_buffer_deliver(struct saa7164_buffer *buf)
index 93a75e15d211e7f1bdef68ab09033fdbb4e534a4..6753008a9c9be4a47e35abf04a20e558157cc1f0 100644 (file)
@@ -328,6 +328,7 @@ int saa7164_cmd_send(struct saa7164_dev *dev,
        u8 id, tmComResCmd_t command, u16 controlselector,
        u16 size, void *buf);
 void saa7164_cmd_signal(struct saa7164_dev *dev, u8 seqno);
+int saa7164_irq_dequeue(struct saa7164_dev *dev);
 
 /* ----------------------------------------------------------- */
 /* saa7164-api.c                                               */