diff options
author | Scott Jiang <scott.jiang.linux@gmail.com> | 2013-01-18 15:09:48 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-02-06 06:16:58 -0500 |
commit | d78a488221059d2bc8627c5175f1d358c57d74a0 (patch) | |
tree | 47a6fea33074594d3a91c433790a6070026b4185 /drivers | |
parent | 1e2043779d8e34013f1563f1b9f3d5604092c29e (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.c | 37 | ||||
-rw-r--r-- | drivers/media/platform/blackfin/ppi.c | 11 |
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(®->status); | 61 | status = bfin_read16(®->status); |
62 | if (status & 0x3000) | ||
63 | ppi->err = true; | ||
62 | bfin_write16(®->status, 0xff00); | 64 | bfin_write16(®->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(®->status); | ||
73 | if (status & 0x2) | ||
74 | ppi->err = true; | ||
68 | bfin_write16(®->status, 0xffff); | 75 | bfin_write16(®->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(®->stat); | ||
84 | if (stat & 0x2) | ||
85 | ppi->err = true; | ||
75 | bfin_write32(®->stat, 0xc0ff); | 86 | bfin_write32(®->stat, 0xc0ff); |
76 | break; | 87 | break; |
77 | } | 88 | } |