[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>
This commit is contained in:
parent
1e2043779d
commit
d78a488221
3 changed files with 33 additions and 18 deletions
|
@ -91,8 +91,6 @@ struct bcap_device {
|
|||
int num_sensor_formats;
|
||||
/* pointing to current video buffer */
|
||||
struct bcap_buffer *cur_frm;
|
||||
/* pointing to next video buffer */
|
||||
struct bcap_buffer *next_frm;
|
||||
/* buffer queue used in videobuf2 */
|
||||
struct vb2_queue buffer_queue;
|
||||
/* allocator-specific contexts for each plane */
|
||||
|
@ -455,10 +453,10 @@ static int bcap_stop_streaming(struct vb2_queue *vq)
|
|||
|
||||
/* release all active buffers */
|
||||
while (!list_empty(&bcap_dev->dma_queue)) {
|
||||
bcap_dev->next_frm = list_entry(bcap_dev->dma_queue.next,
|
||||
bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next,
|
||||
struct bcap_buffer, list);
|
||||
list_del(&bcap_dev->next_frm->list);
|
||||
vb2_buffer_done(&bcap_dev->next_frm->vb, VB2_BUF_STATE_ERROR);
|
||||
list_del(&bcap_dev->cur_frm->list);
|
||||
vb2_buffer_done(&bcap_dev->cur_frm->vb, VB2_BUF_STATE_ERROR);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -535,10 +533,21 @@ static irqreturn_t bcap_isr(int irq, void *dev_id)
|
|||
|
||||
spin_lock(&bcap_dev->lock);
|
||||
|
||||
if (bcap_dev->cur_frm != bcap_dev->next_frm) {
|
||||
if (!list_empty(&bcap_dev->dma_queue)) {
|
||||
v4l2_get_timestamp(&vb->v4l2_buf.timestamp);
|
||||
vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
|
||||
bcap_dev->cur_frm = bcap_dev->next_frm;
|
||||
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 = list_entry(bcap_dev->dma_queue.next,
|
||||
struct bcap_buffer, list);
|
||||
list_del(&bcap_dev->cur_frm->list);
|
||||
} else {
|
||||
/* clear error flag, we will get a new frame */
|
||||
if (ppi->err)
|
||||
ppi->err = false;
|
||||
}
|
||||
|
||||
ppi->ops->stop(ppi);
|
||||
|
@ -546,13 +555,8 @@ static irqreturn_t bcap_isr(int irq, void *dev_id)
|
|||
if (bcap_dev->stop) {
|
||||
complete(&bcap_dev->comp);
|
||||
} else {
|
||||
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->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);
|
||||
}
|
||||
|
||||
|
@ -586,9 +590,8 @@ static int bcap_streamon(struct file *file, void *priv,
|
|||
}
|
||||
|
||||
/* get the next frame from the dma queue */
|
||||
bcap_dev->next_frm = list_entry(bcap_dev->dma_queue.next,
|
||||
bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next,
|
||||
struct bcap_buffer, list);
|
||||
bcap_dev->cur_frm = bcap_dev->next_frm;
|
||||
/* remove buffer from the dma queue */
|
||||
list_del(&bcap_dev->cur_frm->list);
|
||||
addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->cur_frm->vb, 0);
|
||||
|
|
|
@ -59,19 +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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue