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(&reg->status);
+		if (status & 0x3000)
+			ppi->err = true;
 		bfin_write16(&reg->status, 0xff00);
 		break;
 	}
 	case PPI_TYPE_EPPI:
 	{
 		struct bfin_eppi_regs *reg = info->base;
+		unsigned short status;
+
+		status = bfin_read16(&reg->status);
+		if (status & 0x2)
+			ppi->err = true;
 		bfin_write16(&reg->status, 0xffff);
 		break;
 	}
 	case PPI_TYPE_EPPI3:
 	{
 		struct bfin_eppi3_regs *reg = info->base;
+		unsigned long stat;
+
+		stat = bfin_read32(&reg->stat);
+		if (stat & 0x2)
+			ppi->err = true;
 		bfin_write32(&reg->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

Reply via email to