aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorScott Jiang <scott.jiang.linux@gmail.com>2013-01-18 15:09:48 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-02-06 06:16:58 -0500
commitd78a488221059d2bc8627c5175f1d358c57d74a0 (patch)
tree47a6fea33074594d3a91c433790a6070026b4185 /drivers
parent1e2043779d8e34013f1563f1b9f3d5604092c29e (diff)
[media] blackfin: add error frame support
Mark current frame as error frame when ppi error interrupt report fifo error. Member next_frm in struct bcap_device can be optimized out. Signed-off-by: Scott Jiang <scott.jiang.linux@gmail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/platform/blackfin/bfin_capture.c37
-rw-r--r--drivers/media/platform/blackfin/ppi.c11
2 files changed, 31 insertions, 17 deletions
diff --git a/drivers/media/platform/blackfin/bfin_capture.c b/drivers/media/platform/blackfin/bfin_capture.c
index 12e0faf53403..5f209d5810dc 100644
--- a/drivers/media/platform/blackfin/bfin_capture.c
+++ b/drivers/media/platform/blackfin/bfin_capture.c
@@ -91,8 +91,6 @@ struct bcap_device {
91 int num_sensor_formats; 91 int num_sensor_formats;
92 /* pointing to current video buffer */ 92 /* pointing to current video buffer */
93 struct bcap_buffer *cur_frm; 93 struct bcap_buffer *cur_frm;
94 /* pointing to next video buffer */
95 struct bcap_buffer *next_frm;
96 /* buffer queue used in videobuf2 */ 94 /* buffer queue used in videobuf2 */
97 struct vb2_queue buffer_queue; 95 struct vb2_queue buffer_queue;
98 /* allocator-specific contexts for each plane */ 96 /* allocator-specific contexts for each plane */
@@ -455,10 +453,10 @@ static int bcap_stop_streaming(struct vb2_queue *vq)
455 453
456 /* release all active buffers */ 454 /* release all active buffers */
457 while (!list_empty(&bcap_dev->dma_queue)) { 455 while (!list_empty(&bcap_dev->dma_queue)) {
458 bcap_dev->next_frm = list_entry(bcap_dev->dma_queue.next, 456 bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next,
459 struct bcap_buffer, list); 457 struct bcap_buffer, list);
460 list_del(&bcap_dev->next_frm->list); 458 list_del(&bcap_dev->cur_frm->list);
461 vb2_buffer_done(&bcap_dev->next_frm->vb, VB2_BUF_STATE_ERROR); 459 vb2_buffer_done(&bcap_dev->cur_frm->vb, VB2_BUF_STATE_ERROR);
462 } 460 }
463 return 0; 461 return 0;
464} 462}
@@ -535,10 +533,21 @@ static irqreturn_t bcap_isr(int irq, void *dev_id)
535 533
536 spin_lock(&bcap_dev->lock); 534 spin_lock(&bcap_dev->lock);
537 535
538 if (bcap_dev->cur_frm != bcap_dev->next_frm) { 536 if (!list_empty(&bcap_dev->dma_queue)) {
539 v4l2_get_timestamp(&vb->v4l2_buf.timestamp); 537 v4l2_get_timestamp(&vb->v4l2_buf.timestamp);
540 vb2_buffer_done(vb, VB2_BUF_STATE_DONE); 538 if (ppi->err) {
541 bcap_dev->cur_frm = bcap_dev->next_frm; 539 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
540 ppi->err = false;
541 } else {
542 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
543 }
544 bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next,
545 struct bcap_buffer, list);
546 list_del(&bcap_dev->cur_frm->list);
547 } else {
548 /* clear error flag, we will get a new frame */
549 if (ppi->err)
550 ppi->err = false;
542 } 551 }
543 552
544 ppi->ops->stop(ppi); 553 ppi->ops->stop(ppi);
@@ -546,13 +555,8 @@ static irqreturn_t bcap_isr(int irq, void *dev_id)
546 if (bcap_dev->stop) { 555 if (bcap_dev->stop) {
547 complete(&bcap_dev->comp); 556 complete(&bcap_dev->comp);
548 } else { 557 } else {
549 if (!list_empty(&bcap_dev->dma_queue)) { 558 addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->cur_frm->vb, 0);
550 bcap_dev->next_frm = list_entry(bcap_dev->dma_queue.next, 559 ppi->ops->update_addr(ppi, (unsigned long)addr);
551 struct bcap_buffer, list);
552 list_del(&bcap_dev->next_frm->list);
553 addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->next_frm->vb, 0);
554 ppi->ops->update_addr(ppi, (unsigned long)addr);
555 }
556 ppi->ops->start(ppi); 560 ppi->ops->start(ppi);
557 } 561 }
558 562
@@ -586,9 +590,8 @@ static int bcap_streamon(struct file *file, void *priv,
586 } 590 }
587 591
588 /* get the next frame from the dma queue */ 592 /* get the next frame from the dma queue */
589 bcap_dev->next_frm = list_entry(bcap_dev->dma_queue.next, 593 bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next,
590 struct bcap_buffer, list); 594 struct bcap_buffer, list);
591 bcap_dev->cur_frm = bcap_dev->next_frm;
592 /* remove buffer from the dma queue */ 595 /* remove buffer from the dma queue */
593 list_del(&bcap_dev->cur_frm->list); 596 list_del(&bcap_dev->cur_frm->list);
594 addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->cur_frm->vb, 0); 597 addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->cur_frm->vb, 0);
diff --git a/drivers/media/platform/blackfin/ppi.c b/drivers/media/platform/blackfin/ppi.c
index 1e24584605f2..01b5b501347e 100644
--- a/drivers/media/platform/blackfin/ppi.c
+++ b/drivers/media/platform/blackfin/ppi.c
@@ -59,19 +59,30 @@ static irqreturn_t ppi_irq_err(int irq, void *dev_id)
59 * others are W1C 59 * others are W1C
60 */ 60 */
61 status = bfin_read16(&reg->status); 61 status = bfin_read16(&reg->status);
62 if (status & 0x3000)
63 ppi->err = true;
62 bfin_write16(&reg->status, 0xff00); 64 bfin_write16(&reg->status, 0xff00);
63 break; 65 break;
64 } 66 }
65 case PPI_TYPE_EPPI: 67 case PPI_TYPE_EPPI:
66 { 68 {
67 struct bfin_eppi_regs *reg = info->base; 69 struct bfin_eppi_regs *reg = info->base;
70 unsigned short status;
71
72 status = bfin_read16(&reg->status);
73 if (status & 0x2)
74 ppi->err = true;
68 bfin_write16(&reg->status, 0xffff); 75 bfin_write16(&reg->status, 0xffff);
69 break; 76 break;
70 } 77 }
71 case PPI_TYPE_EPPI3: 78 case PPI_TYPE_EPPI3:
72 { 79 {
73 struct bfin_eppi3_regs *reg = info->base; 80 struct bfin_eppi3_regs *reg = info->base;
81 unsigned long stat;
74 82
83 stat = bfin_read32(&reg->stat);
84 if (stat & 0x2)
85 ppi->err = true;
75 bfin_write32(&reg->stat, 0xc0ff); 86 bfin_write32(&reg->stat, 0xc0ff);
76 break; 87 break;
77 } 88 }