mirror of
https://github.com/torvalds/linux.git
synced 2024-12-26 21:02:19 +00:00
[media] v4l: omap4iss: Cancel streaming when a fatal error occurs
When a fatal error that prevents any further video streaming occurs in a pipeline, all queued buffers must be marked as erroneous and new buffers must be prevented from being queued. Implement this behaviour with a new omap4iss_pipeline_cancel_stream() function that can be used by submodules to cancel streaming. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
This commit is contained in:
parent
216814fb01
commit
112da08512
@ -692,6 +692,23 @@ int omap4iss_pipeline_set_stream(struct iss_pipeline *pipe,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* omap4iss_pipeline_cancel_stream - Cancel stream on a pipeline
|
||||
* @pipe: ISS pipeline
|
||||
*
|
||||
* Cancelling a stream mark all buffers on all video nodes in the pipeline as
|
||||
* erroneous and makes sure no new buffer can be queued. This function is called
|
||||
* when a fatal error that prevents any further operation on the pipeline
|
||||
* occurs.
|
||||
*/
|
||||
void omap4iss_pipeline_cancel_stream(struct iss_pipeline *pipe)
|
||||
{
|
||||
if (pipe->input)
|
||||
omap4iss_video_cancel_stream(pipe->input);
|
||||
if (pipe->output)
|
||||
omap4iss_video_cancel_stream(pipe->output);
|
||||
}
|
||||
|
||||
/*
|
||||
* iss_pipeline_is_last - Verify if entity has an enabled link to the output
|
||||
* video node
|
||||
|
@ -131,6 +131,7 @@ int omap4iss_module_sync_is_stopping(wait_queue_head_t *wait,
|
||||
|
||||
int omap4iss_pipeline_set_stream(struct iss_pipeline *pipe,
|
||||
enum iss_pipeline_stream_state state);
|
||||
void omap4iss_pipeline_cancel_stream(struct iss_pipeline *pipe);
|
||||
|
||||
void omap4iss_configure_bridge(struct iss_device *iss,
|
||||
enum ipipeif_input_entity input);
|
||||
|
@ -312,7 +312,7 @@ void omap4iss_resizer_isr(struct iss_resizer_device *resizer, u32 events)
|
||||
dev_dbg(iss->dev, "RSZ Err: FIFO_IN_BLK:%d, FIFO_OVF:%d\n",
|
||||
events & ISP5_IRQ_RSZ_FIFO_IN_BLK_ERR ? 1 : 0,
|
||||
events & ISP5_IRQ_RSZ_FIFO_OVF ? 1 : 0);
|
||||
pipe->error = true;
|
||||
omap4iss_pipeline_cancel_stream(pipe);
|
||||
}
|
||||
|
||||
if (omap4iss_module_sync_is_stopping(&resizer->wait,
|
||||
|
@ -328,6 +328,15 @@ static int iss_video_buf_prepare(struct vb2_buffer *vb)
|
||||
if (vb2_plane_size(vb, 0) < size)
|
||||
return -ENOBUFS;
|
||||
|
||||
/* Refuse to prepare the buffer is the video node has registered an
|
||||
* error. We don't need to take any lock here as the operation is
|
||||
* inherently racy. The authoritative check will be performed in the
|
||||
* queue handler, which can't return an error, this check is just a best
|
||||
* effort to notify userspace as early as possible.
|
||||
*/
|
||||
if (unlikely(video->error))
|
||||
return -EIO;
|
||||
|
||||
addr = vb2_dma_contig_plane_dma_addr(vb, 0);
|
||||
if (!IS_ALIGNED(addr, 32)) {
|
||||
dev_dbg(video->iss->dev,
|
||||
@ -346,12 +355,20 @@ static void iss_video_buf_queue(struct vb2_buffer *vb)
|
||||
struct iss_video *video = vfh->video;
|
||||
struct iss_buffer *buffer = container_of(vb, struct iss_buffer, vb);
|
||||
struct iss_pipeline *pipe = to_iss_pipeline(&video->video.entity);
|
||||
unsigned int empty;
|
||||
unsigned long flags;
|
||||
bool empty;
|
||||
|
||||
spin_lock_irqsave(&video->qlock, flags);
|
||||
|
||||
if (unlikely(video->error)) {
|
||||
vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
|
||||
spin_unlock_irqrestore(&video->qlock, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
empty = list_empty(&video->dmaqueue);
|
||||
list_add_tail(&buffer->list, &video->dmaqueue);
|
||||
|
||||
spin_unlock_irqrestore(&video->qlock, flags);
|
||||
|
||||
if (empty) {
|
||||
@ -471,6 +488,33 @@ struct iss_buffer *omap4iss_video_buffer_next(struct iss_video *video)
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* omap4iss_video_cancel_stream - Cancel stream on a video node
|
||||
* @video: ISS video object
|
||||
*
|
||||
* Cancelling a stream mark all buffers on the video node as erroneous and makes
|
||||
* sure no new buffer can be queued.
|
||||
*/
|
||||
void omap4iss_video_cancel_stream(struct iss_video *video)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&video->qlock, flags);
|
||||
|
||||
while (!list_empty(&video->dmaqueue)) {
|
||||
struct iss_buffer *buf;
|
||||
|
||||
buf = list_first_entry(&video->dmaqueue, struct iss_buffer,
|
||||
list);
|
||||
list_del(&buf->list);
|
||||
vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
|
||||
}
|
||||
|
||||
video->error = true;
|
||||
|
||||
spin_unlock_irqrestore(&video->qlock, flags);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* V4L2 ioctls
|
||||
*/
|
||||
@ -852,6 +896,7 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
|
||||
video->queue = &vfh->queue;
|
||||
INIT_LIST_HEAD(&video->dmaqueue);
|
||||
spin_lock_init(&video->qlock);
|
||||
video->error = false;
|
||||
atomic_set(&pipe->frame_number, -1);
|
||||
|
||||
ret = vb2_streamon(&vfh->queue, type);
|
||||
|
@ -163,10 +163,11 @@ struct iss_video {
|
||||
/* Pipeline state */
|
||||
struct iss_pipeline pipe;
|
||||
struct mutex stream_lock; /* pipeline and stream states */
|
||||
bool error;
|
||||
|
||||
/* Video buffers queue */
|
||||
struct vb2_queue *queue;
|
||||
spinlock_t qlock; /* Spinlock for dmaqueue */
|
||||
spinlock_t qlock; /* protects dmaqueue and error */
|
||||
struct list_head dmaqueue;
|
||||
enum iss_video_dmaqueue_flags dmaqueue_flags;
|
||||
struct vb2_alloc_ctx *alloc_ctx;
|
||||
@ -194,6 +195,7 @@ int omap4iss_video_register(struct iss_video *video,
|
||||
struct v4l2_device *vdev);
|
||||
void omap4iss_video_unregister(struct iss_video *video);
|
||||
struct iss_buffer *omap4iss_video_buffer_next(struct iss_video *video);
|
||||
void omap4iss_video_cancel_stream(struct iss_video *video);
|
||||
struct media_pad *omap4iss_video_remote_pad(struct iss_video *video);
|
||||
|
||||
const struct iss_format_info *
|
||||
|
Loading…
Reference in New Issue
Block a user