summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Toth <stoth@kernellabs.com>2010-07-31 15:49:28 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-10-21 07:54:59 -0200
commitcfbaf33733b99d214d5616dcb48a690630c19d65 (patch)
treecc5c1f8e94e6ed2773d02b4224462baf61f44771
parentb31f1222990c02bccb73805648493b5e132a52f9 (diff)
[media] saa7164: irqhandler cleanup and helper function added
Signed-off-by: Steven Toth <stoth@kernellabs.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/saa7164/saa7164-core.c252
-rw-r--r--drivers/media/video/saa7164/saa7164.h4
2 files changed, 80 insertions, 176 deletions
diff --git a/drivers/media/video/saa7164/saa7164-core.c b/drivers/media/video/saa7164/saa7164-core.c
index 09f7a64f538b..eb9c3459bb10 100644
--- a/drivers/media/video/saa7164/saa7164-core.c
+++ b/drivers/media/video/saa7164/saa7164-core.c
@@ -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;
}
diff --git a/drivers/media/video/saa7164/saa7164.h b/drivers/media/video/saa7164/saa7164.h
index 58141dfed246..9c76e65b9785 100644
--- a/drivers/media/video/saa7164/saa7164.h
+++ b/drivers/media/video/saa7164/saa7164.h
@@ -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;