commit: http://blackfin.uclinux.org/git/?p=linux-kernel;a=commitdiff;h=fd625f3434fc86ef5bb41af66126044b99963da9 branch: http://blackfin.uclinux.org/git/?p=linux-kernel;a=shortlog;h=refs/heads/trunk
We mark current frame error if ppi has fifo error. Signed-off-by: Scott Jiang <[email protected]> --- drivers/media/video/blackfin/bfin_capture.c | 20 +++++++++++++++++--- drivers/media/video/blackfin/ppi.c | 12 ++++++++++++ include/media/blackfin/ppi.h | 3 ++- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/drivers/media/video/blackfin/bfin_capture.c b/drivers/media/video/blackfin/bfin_capture.c index 05a89b5..429cec8 100644 --- a/drivers/media/video/blackfin/bfin_capture.c +++ b/drivers/media/video/blackfin/bfin_capture.c @@ -530,8 +530,17 @@ static irqreturn_t bcap_isr(int irq, void *dev_id) if (bcap_dev->cur_frm != bcap_dev->next_frm) { do_gettimeofday(&timevalue); vb->v4l2_buf.timestamp = timevalue; - vb2_buffer_done(vb, VB2_BUF_STATE_DONE); + if (ppi->err) { + vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); + ppi->err = false; + } else { + vb2_buffer_done(vb, VB2_BUF_STATE_DONE); + } bcap_dev->cur_frm = bcap_dev->next_frm; + } else { + /* clear error flag, we will get a new frame */ + if (ppi->err) + ppi->err = false; } ppi->ops->stop(ppi); @@ -543,9 +552,9 @@ static irqreturn_t bcap_isr(int irq, void *dev_id) bcap_dev->next_frm = list_entry(bcap_dev->dma_queue.next, struct bcap_buffer, list); list_del(&bcap_dev->next_frm->list); - addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->next_frm->vb, 0); - ppi->ops->update_addr(ppi, (unsigned long)addr); } + addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->cur_frm->vb, 0); + ppi->ops->update_addr(ppi, (unsigned long)addr); ppi->ops->start(ppi); } @@ -584,6 +593,11 @@ static int bcap_streamon(struct file *file, void *priv, bcap_dev->cur_frm = bcap_dev->next_frm; /* remove buffer from the dma queue */ list_del(&bcap_dev->cur_frm->list); + if (!list_empty(&bcap_dev->dma_queue)) { + bcap_dev->next_frm = list_entry(bcap_dev->dma_queue.next, + struct bcap_buffer, list); + list_del(&bcap_dev->next_frm->list); + } addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->cur_frm->vb, 0); /* update DMA address */ ppi->ops->update_addr(ppi, (unsigned long)addr); diff --git a/drivers/media/video/blackfin/ppi.c b/drivers/media/video/blackfin/ppi.c index 4bb63a0..7233ab1 100644 --- a/drivers/media/video/blackfin/ppi.c +++ b/drivers/media/video/blackfin/ppi.c @@ -59,18 +59,30 @@ static irqreturn_t ppi_irq_err(int irq, void *dev_id) * others are W1C */ status = bfin_read16(®->status); + if (status & 0x3000) + ppi->err = true; bfin_write16(®->status, 0xff00); break; } case PPI_TYPE_EPPI: { struct bfin_eppi_regs *reg = info->base; + unsigned short status; + + status = bfin_read16(®->status); + if (status & 0x2) + ppi->err = true; bfin_write16(®->status, 0xffff); break; } case PPI_TYPE_EPPI3: { struct bfin_eppi3_regs *reg = info->base; + unsigned long stat; + + stat = bfin_read32(®->stat); + if (stat & 0x2) + ppi->err = true; bfin_write32(®->stat, 0xc0ff); break; } diff --git a/include/media/blackfin/ppi.h b/include/media/blackfin/ppi.h index 65c4675..d0697f4 100644 --- a/include/media/blackfin/ppi.h +++ b/include/media/blackfin/ppi.h @@ -86,7 +86,8 @@ struct ppi_if { unsigned long ppi_control; const struct ppi_ops *ops; const struct ppi_info *info; - bool err_int; + bool err_int; /* if we need request error interrupt */ + bool err; /* if ppi has fifo error */ void *priv; };
_______________________________________________ Linux-kernel-commits mailing list [email protected] https://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits
