[media] saa7164: irqhandler cleanup and helper function added
authorSteven Toth <stoth@kernellabs.com>
Sat, 31 Jul 2010 18:49:28 +0000 (15:49 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Thu, 21 Oct 2010 09:54:59 +0000 (07:54 -0200)
Signed-off-by: Steven Toth <stoth@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/saa7164/saa7164-core.c
drivers/media/video/saa7164/saa7164.h

index 09f7a64f538bf6e1d16754f5a677d6e7a9418106..eb9c3459bb10fefe80afab294494ea7558c5a97e 100644 (file)
@@ -239,54 +239,15 @@ static void saa7164_histogram_print(struct saa7164_port *port,
        printk(KERN_ERR "Total: %d\n", entries);
 }
 
-static void saa7164_work_enchandler(struct work_struct *w)
+static void saa7164_work_enchandler_helper(struct saa7164_port *port, int bufnr)
 {
-       struct saa7164_port *port =
-               container_of(w, struct saa7164_port, workenc);
        struct saa7164_dev *dev = port->dev;
-       struct saa7164_buffer *buf;
-       struct saa7164_user_buffer *ubuf;
+       struct saa7164_buffer *buf = 0;
+       struct saa7164_user_buffer *ubuf = 0;
        struct list_head *c, *n;
-       int wp, rp, i = 0;
-       u32 crc, ok = 0;
-       u8 *p;
-
-       port->last_svc_msecs_diff = port->last_svc_msecs;
-       port->last_svc_msecs = jiffies_to_msecs(jiffies);
-       port->last_svc_wp = saa7164_readl(port->bufcounter);
-       port->last_svc_rp = port->last_irq_rp;
-       wp = port->last_svc_wp;
-       rp = port->last_svc_rp;
-
-
-       port->last_svc_msecs_diff = port->last_svc_msecs -
-               port->last_svc_msecs_diff;
-
-       saa7164_histogram_update(&port->svc_interval,
-               port->last_svc_msecs_diff);
-
-       port->last_irq_svc_msecs_diff = port->last_svc_msecs -
-               port->last_irq_msecs;
-
-       saa7164_histogram_update(&port->irq_svc_interval,
-               port->last_irq_svc_msecs_diff);
-
-       dprintk(DBGLVL_IRQ,
-               "%s() %Ldms elapsed irq->deferred %Ldms wp: %d rp: %d\n",
-               __func__,
-               port->last_svc_msecs_diff,
-               port->last_irq_svc_msecs_diff,
-               port->last_svc_wp,
-               port->last_svc_rp
-               );
-
-       if ((rp < 0) || (rp > 7)) {
-               printk(KERN_ERR "%s() illegal rp count %d\n", __func__, rp);
-               return;
-       }
+       int i = 0;
 
        mutex_lock(&port->dmaqueue_lock);
-
        list_for_each_safe(c, n, &port->dmaqueue.list) {
 
                buf = list_entry(c, struct saa7164_buffer, list);
@@ -296,33 +257,10 @@ static void saa7164_work_enchandler(struct work_struct *w)
                        break;
                }
 
-               p = (u8 *)buf->cpu;
-               if (    (*(p + buf->actual_size + 0) != 0xff) ||
-                       (*(p + buf->actual_size + 1) != 0xff) ||
-                       (*(p + buf->actual_size + 2) != 0xff) ||
-                       (*(p + buf->actual_size + 3) != 0xff) ||
-                       (*(p + buf->actual_size + 0x10) != 0xff) ||
-                       (*(p + buf->actual_size + 0x11) != 0xff) ||
-                       (*(p + buf->actual_size + 0x12) != 0xff) ||
-                       (*(p + buf->actual_size + 0x13) != 0xff) )
-               {
-                       printk(KERN_ERR "%s() buf %p failed guard check\n", __func__, buf);
-                       saa7164_dumphex16(dev, p + buf->actual_size - 32, 64);
-               }
-
-               if (buf->idx == wp) {
-                       /* Ignore this, it's being updated currently by the dma engine */
-               } else
-               if (buf->idx == rp) {
-
-                       crc = crc32(0, buf->cpu, buf->actual_size);
-//                     if (crc != port->shadow_crc[rp])
-//                             printk(KERN_ERR "%s crc didn't match shadow was 0x%x now 0x%x\n",
-//                                     __func__, port->shadow_crc[rp], crc);
+               if (buf->idx == bufnr) {
 
                        /* Found the buffer, deal with it */
-                       dprintk(DBGLVL_IRQ, "%s() wp: %d processing: %d crc32: 0x%x\n",
-                               __func__, wp, rp, buf->crc);
+                       dprintk(DBGLVL_IRQ, "%s() rp: %d\n", __func__, bufnr);
 
                        /* Validate the incoming buffer content */
                        if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_TS)
@@ -339,17 +277,12 @@ static void saa7164_work_enchandler(struct work_struct *w)
 
                                if (buf->actual_size <= ubuf->actual_size) {
 
-                                       memcpy_fromio(ubuf->data, port->shadow_buf[rp],
+                                       memcpy_fromio(ubuf->data, buf->cpu,
                                                ubuf->actual_size);
 
                                        /* Throw a new checksum on the read buffer */
                                        ubuf->crc = crc32(0, ubuf->data, ubuf->actual_size);
 
-                                       if ((crc == port->shadow_crc[rp]) && (crc == ubuf->crc))
-                                               ok = 1;
-                                       else
-                                               ok = 0;
-
                                        /* Requeue the buffer on the free list */
                                        ubuf->pos = 0;
 
@@ -369,26 +302,81 @@ static void saa7164_work_enchandler(struct work_struct *w)
                        /* Ensure offset into buffer remains 0, fill buffer
                         * with known bad data. We check for this data at a later point
                         * in time. */
-                       saa7164_buffer_zero_offsets(port, rp);
+                       saa7164_buffer_zero_offsets(port, bufnr);
                        memset_io(buf->cpu, 0xff, buf->pci_size);
-                       buf->crc = crc32(0, buf->cpu, buf->actual_size);
 
                        break;
-               } else {
-                       /* Validate all other checksums, on previous buffers - they should never change */
-                       crc = crc32(0, buf->cpu, buf->actual_size);
-                       if (crc != buf->crc) {
-                               printk(KERN_ERR "buf[%d].crc became invalid, was 0x%x became 0x%x rp: %d wp: %d\n",
-                                       buf->idx, buf->crc, crc, rp, wp);
-                               //saa7164_dumphex16FF(dev, (u8 *)buf->cpu, buf->actual_size);
-                               saa7164_dumphex16FF(dev, (u8 *)buf->cpu, 256);
-                               buf->crc = crc;
-                       }
+               }
+       }
+       mutex_unlock(&port->dmaqueue_lock);
+}
+
+static void saa7164_work_enchandler(struct work_struct *w)
+{
+       struct saa7164_port *port =
+               container_of(w, struct saa7164_port, workenc);
+       struct saa7164_dev *dev = port->dev;
+
+       u32 wp, mcb, rp, cnt = 0;
 
+       port->last_svc_msecs_diff = port->last_svc_msecs;
+       port->last_svc_msecs = jiffies_to_msecs(jiffies);
+
+       port->last_svc_msecs_diff = port->last_svc_msecs -
+               port->last_svc_msecs_diff;
+
+       saa7164_histogram_update(&port->svc_interval,
+               port->last_svc_msecs_diff);
+
+       port->last_irq_svc_msecs_diff = port->last_svc_msecs -
+               port->last_irq_msecs;
+
+       saa7164_histogram_update(&port->irq_svc_interval,
+               port->last_irq_svc_msecs_diff);
+
+       dprintk(DBGLVL_IRQ,
+               "%s() %Ldms elapsed irq->deferred %Ldms wp: %d rp: %d\n",
+               __func__,
+               port->last_svc_msecs_diff,
+               port->last_irq_svc_msecs_diff,
+               port->last_svc_wp,
+               port->last_svc_rp
+               );
+
+       /* Current write position */
+       wp = saa7164_readl(port->bufcounter);
+       if (wp > (port->hwcfg.buffercount - 1)) {
+               printk(KERN_ERR "%s() illegal buf count %d\n", __func__, wp);
+               return;
+       }
+
+       /* Most current complete buffer */
+       if (wp == 0)
+               mcb = 7;
+       else
+               mcb = wp - 1;
+
+       while (1) {
+               rp = (port->last_svc_rp + 1) % 8;
+
+               if ((rp < 0) || (rp > 7)) {
+                       printk(KERN_ERR "%s() illegal rp count %d\n", __func__, rp);
+                       break;
                }
 
+               /* Process a buffer */
+               if (port->nr == SAA7164_PORT_ENC1)
+                       printk(KERN_ERR "Port enc1 processing buffer %d\n", rp);
+               saa7164_work_enchandler_helper(port, rp);
+               port->last_svc_rp = rp;
+               cnt++;
+
+               if (rp == mcb)
+                       break;
        }
-       mutex_unlock(&port->dmaqueue_lock);
+
+       if (port->nr == SAA7164_PORT_ENC1)
+               printk(KERN_ERR "Enc1 processed %d buffers for port %p\n", cnt, port);
 
        if (print_histogram == port->nr) {
                saa7164_histogram_print(port, &port->irq_interval);
@@ -399,6 +387,7 @@ static void saa7164_work_enchandler(struct work_struct *w)
                print_histogram = 64 + port->nr;
        }
 }
+
 static void saa7164_work_cmdhandler(struct work_struct *w)
 {
        struct saa7164_dev *dev = container_of(w, struct saa7164_dev, workcmd);
@@ -420,49 +409,12 @@ static void saa7164_buffer_deliver(struct saa7164_buffer *buf)
 static irqreturn_t saa7164_irq_encoder(struct saa7164_port *port)
 {
        struct saa7164_dev *dev = port->dev;
-       struct saa7164_buffer *buf;
-       struct list_head *c, *n;
-       int wp, rp, i = 0;
-       u8 *p;
-       u32 *up, j;
-
-       /* Find the current write point from the hardware */
-       wp = saa7164_readl(port->bufcounter);
-       if (wp > (port->hwcfg.buffercount - 1)) {
-               printk(KERN_ERR "%s() illegal buf count %d\n", __func__, wp);
-               return 0;
-       }
-
-       printk(KERN_ERR "port %p wp = %d\n", port, wp);
-
-       /* Find the previous buffer to the current write point */
-       if (wp == 0)
-               rp = 7;
-       else
-               rp = wp - 1;
-
-       if ((rp < 0) || (rp > 7)) {
-               printk(KERN_ERR "%s() illegal rp count %d\n", __func__, rp);
-               return 0;
-       }
-
-       if (rp == port->last_irq_rp) {
-               printk(KERN_ERR "%s() Duplicate rp = %d port %p\n",
-                       __func__, rp, port);
-       }
-
-       if (rp != ((port->last_irq_rp + 1) % 8)) {
-               printk(KERN_ERR "%s() Multiple bufs on interrupt, port %p\n",
-                       __func__, port);
-       }
 
        /* Store old time */
        port->last_irq_msecs_diff = port->last_irq_msecs;
 
        /* Collect new stats */
        port->last_irq_msecs = jiffies_to_msecs(jiffies);
-       port->last_irq_wp = wp;
-       port->last_irq_rp = rp;
 
        /* Calculate stats */
        port->last_irq_msecs_diff = port->last_irq_msecs -
@@ -471,58 +423,10 @@ static irqreturn_t saa7164_irq_encoder(struct saa7164_port *port)
        saa7164_histogram_update(&port->irq_interval,
                port->last_irq_msecs_diff);
 
-       dprintk(DBGLVL_IRQ, "%s() %Ldms elapsed wp: %d rp: %d\n",
-               __func__,
-               port->last_irq_msecs_diff,
-               port->last_irq_wp,
-               port->last_irq_rp
-               );
-       /* Find the used buffer, shadow copy it before we've
-        * acked the interrupt.
-        */
-//     mutex_lock(&port->dmaqueue_lock);
-       list_for_each_safe(c, n, &port->dmaqueue.list) {
-
-               buf = list_entry(c, struct saa7164_buffer, list);
-               if (i++ > port->hwcfg.buffercount) {
-                       printk(KERN_ERR "%s() illegal i count %d\n",
-                               __func__, i);
-                       break;
-               }
-
-               p = (u8 *)buf->cpu;
-               if (    (*(p + buf->actual_size + 0) != 0xff) ||
-                       (*(p + buf->actual_size + 1) != 0xff) ||
-                       (*(p + buf->actual_size + 2) != 0xff) ||
-                       (*(p + buf->actual_size + 3) != 0xff) ||
-                       (*(p + buf->actual_size + 0x10) != 0xff) ||
-                       (*(p + buf->actual_size + 0x11) != 0xff) ||
-                       (*(p + buf->actual_size + 0x12) != 0xff) ||
-                       (*(p + buf->actual_size + 0x13) != 0xff) )
-               {
-                       printk(KERN_ERR "buf %p failed guard check\n", buf);
-                       saa7164_dumphex16(dev, p + buf->actual_size - 32, 64);
-               }
-
-               if (buf->idx == rp) {
-                       up = (u32 *)port->shadow_buf[rp];
-                       for (j = 0 ; j < (buf->actual_size / sizeof(u32)); j++) {
-                               *(up + j) = (rp << 28) | port->counter++;
-                       }
-                       port->shadow_crc[rp] = crc32(0, port->shadow_buf[rp], buf->actual_size);
-
-                       buf->crc = crc32(0, buf->cpu, buf->actual_size);
-
-//                     if (port->shadow_crc[rp] != buf->crc)
-//                             printk(KERN_ERR "%s() crc check failed 0x%x vs 0x%x\n",
-//                                     __func__, port->shadow_crc[rp], buf->crc);
-                       break;
-               }
+       dprintk(DBGLVL_IRQ, "%s() %Ldms elapsed\n", __func__,
+               port->last_irq_msecs_diff);
 
-       }
-//     mutex_unlock(&port->dmaqueue_lock);
        schedule_work(&port->workenc);
-
        return 0;
 }
 
index 58141dfed246d856ff35a6c156d948c58aec55ab..9c76e65b978580142abc8f3b5c420666d496bb1f 100644 (file)
@@ -330,8 +330,8 @@ struct saa7164_port {
 
        u64 last_irq_msecs, last_svc_msecs;
        u64 last_irq_msecs_diff, last_svc_msecs_diff;
-       u32 last_irq_wp, last_svc_wp;
-       u32 last_irq_rp, last_svc_rp;
+       u32 last_svc_wp;
+       u32 last_svc_rp;
        u64 last_irq_svc_msecs_diff;
        u64 last_read_msecs, last_read_msecs_diff;
        u64 last_poll_msecs, last_poll_msecs_diff;