[media] omap3isp: Move queue irqlock to isp_video structure
This prepares for the move to videobuf2. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Sakari Ailus <sakari.ailus@iki.fi> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
This commit is contained in:
parent
988d54c4b9
commit
e8feb876d4
5 changed files with 19 additions and 27 deletions
|
@ -1399,14 +1399,14 @@ int omap3isp_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait,
|
||||||
if (isp_pipeline_is_last(me)) {
|
if (isp_pipeline_is_last(me)) {
|
||||||
struct isp_video *video = pipe->output;
|
struct isp_video *video = pipe->output;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
spin_lock_irqsave(&video->queue->irqlock, flags);
|
spin_lock_irqsave(&video->irqlock, flags);
|
||||||
if (video->dmaqueue_flags & ISP_VIDEO_DMAQUEUE_UNDERRUN) {
|
if (video->dmaqueue_flags & ISP_VIDEO_DMAQUEUE_UNDERRUN) {
|
||||||
spin_unlock_irqrestore(&video->queue->irqlock, flags);
|
spin_unlock_irqrestore(&video->irqlock, flags);
|
||||||
atomic_set(stopping, 0);
|
atomic_set(stopping, 0);
|
||||||
smp_mb();
|
smp_mb();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&video->queue->irqlock, flags);
|
spin_unlock_irqrestore(&video->irqlock, flags);
|
||||||
if (!wait_event_timeout(*wait, !atomic_read(stopping),
|
if (!wait_event_timeout(*wait, !atomic_read(stopping),
|
||||||
msecs_to_jiffies(1000))) {
|
msecs_to_jiffies(1000))) {
|
||||||
atomic_set(stopping, 0);
|
atomic_set(stopping, 0);
|
||||||
|
|
|
@ -660,7 +660,6 @@ int omap3isp_video_queue_init(struct isp_video_queue *queue,
|
||||||
struct device *dev, unsigned int bufsize)
|
struct device *dev, unsigned int bufsize)
|
||||||
{
|
{
|
||||||
INIT_LIST_HEAD(&queue->queue);
|
INIT_LIST_HEAD(&queue->queue);
|
||||||
spin_lock_init(&queue->irqlock);
|
|
||||||
|
|
||||||
queue->type = type;
|
queue->type = type;
|
||||||
queue->ops = ops;
|
queue->ops = ops;
|
||||||
|
@ -761,7 +760,6 @@ int omap3isp_video_queue_qbuf(struct isp_video_queue *queue,
|
||||||
struct v4l2_buffer *vbuf)
|
struct v4l2_buffer *vbuf)
|
||||||
{
|
{
|
||||||
struct isp_video_buffer *buf;
|
struct isp_video_buffer *buf;
|
||||||
unsigned long flags;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (vbuf->type != queue->type)
|
if (vbuf->type != queue->type)
|
||||||
|
@ -801,11 +799,8 @@ int omap3isp_video_queue_qbuf(struct isp_video_queue *queue,
|
||||||
buf->state = ISP_BUF_STATE_QUEUED;
|
buf->state = ISP_BUF_STATE_QUEUED;
|
||||||
list_add_tail(&buf->stream, &queue->queue);
|
list_add_tail(&buf->stream, &queue->queue);
|
||||||
|
|
||||||
if (queue->streaming) {
|
if (queue->streaming)
|
||||||
spin_lock_irqsave(&queue->irqlock, flags);
|
|
||||||
queue->ops->buffer_queue(buf);
|
queue->ops->buffer_queue(buf);
|
||||||
spin_unlock_irqrestore(&queue->irqlock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -862,17 +857,14 @@ int omap3isp_video_queue_dqbuf(struct isp_video_queue *queue,
|
||||||
int omap3isp_video_queue_streamon(struct isp_video_queue *queue)
|
int omap3isp_video_queue_streamon(struct isp_video_queue *queue)
|
||||||
{
|
{
|
||||||
struct isp_video_buffer *buf;
|
struct isp_video_buffer *buf;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (queue->streaming)
|
if (queue->streaming)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
queue->streaming = 1;
|
queue->streaming = 1;
|
||||||
|
|
||||||
spin_lock_irqsave(&queue->irqlock, flags);
|
|
||||||
list_for_each_entry(buf, &queue->queue, stream)
|
list_for_each_entry(buf, &queue->queue, stream)
|
||||||
queue->ops->buffer_queue(buf);
|
queue->ops->buffer_queue(buf);
|
||||||
spin_unlock_irqrestore(&queue->irqlock, flags);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -890,7 +882,6 @@ int omap3isp_video_queue_streamon(struct isp_video_queue *queue)
|
||||||
void omap3isp_video_queue_streamoff(struct isp_video_queue *queue)
|
void omap3isp_video_queue_streamoff(struct isp_video_queue *queue)
|
||||||
{
|
{
|
||||||
struct isp_video_buffer *buf;
|
struct isp_video_buffer *buf;
|
||||||
unsigned long flags;
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
if (!queue->streaming)
|
if (!queue->streaming)
|
||||||
|
@ -898,7 +889,6 @@ void omap3isp_video_queue_streamoff(struct isp_video_queue *queue)
|
||||||
|
|
||||||
queue->streaming = 0;
|
queue->streaming = 0;
|
||||||
|
|
||||||
spin_lock_irqsave(&queue->irqlock, flags);
|
|
||||||
for (i = 0; i < queue->count; ++i) {
|
for (i = 0; i < queue->count; ++i) {
|
||||||
buf = queue->buffers[i];
|
buf = queue->buffers[i];
|
||||||
|
|
||||||
|
@ -907,7 +897,6 @@ void omap3isp_video_queue_streamoff(struct isp_video_queue *queue)
|
||||||
|
|
||||||
buf->state = ISP_BUF_STATE_IDLE;
|
buf->state = ISP_BUF_STATE_IDLE;
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&queue->irqlock, flags);
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&queue->queue);
|
INIT_LIST_HEAD(&queue->queue);
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,8 +114,7 @@ struct isp_video_buffer {
|
||||||
* the userspace memory address for a USERPTR buffer, with the queue lock
|
* the userspace memory address for a USERPTR buffer, with the queue lock
|
||||||
* held. Drivers should perform device-specific buffer preparation (such as
|
* held. Drivers should perform device-specific buffer preparation (such as
|
||||||
* mapping the buffer memory in an IOMMU). This operation is optional.
|
* mapping the buffer memory in an IOMMU). This operation is optional.
|
||||||
* @buffer_queue: Called when a buffer is being added to the queue with the
|
* @buffer_queue: Called when a buffer is being added.
|
||||||
* queue irqlock spinlock held.
|
|
||||||
*/
|
*/
|
||||||
struct isp_video_queue_operations {
|
struct isp_video_queue_operations {
|
||||||
void (*queue_prepare)(struct isp_video_queue *queue,
|
void (*queue_prepare)(struct isp_video_queue *queue,
|
||||||
|
@ -132,7 +131,6 @@ struct isp_video_queue_operations {
|
||||||
* @bufsize: Size of a driver-specific buffer object
|
* @bufsize: Size of a driver-specific buffer object
|
||||||
* @count: Number of currently allocated buffers
|
* @count: Number of currently allocated buffers
|
||||||
* @buffers: ISP video buffers
|
* @buffers: ISP video buffers
|
||||||
* @irqlock: Spinlock to protect access to the IRQ queue
|
|
||||||
* @streaming: Queue state, indicates whether the queue is streaming
|
* @streaming: Queue state, indicates whether the queue is streaming
|
||||||
* @queue: List of all queued buffers
|
* @queue: List of all queued buffers
|
||||||
*/
|
*/
|
||||||
|
@ -144,7 +142,6 @@ struct isp_video_queue {
|
||||||
|
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
struct isp_video_buffer *buffers[ISP_VIDEO_MAX_BUFFERS];
|
struct isp_video_buffer *buffers[ISP_VIDEO_MAX_BUFFERS];
|
||||||
spinlock_t irqlock;
|
|
||||||
|
|
||||||
unsigned int streaming:1;
|
unsigned int streaming:1;
|
||||||
|
|
||||||
|
|
|
@ -381,15 +381,20 @@ static void isp_video_buffer_queue(struct isp_video_buffer *buf)
|
||||||
unsigned int empty;
|
unsigned int empty;
|
||||||
unsigned int start;
|
unsigned int start;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&video->irqlock, flags);
|
||||||
|
|
||||||
if (unlikely(video->error)) {
|
if (unlikely(video->error)) {
|
||||||
buf->state = ISP_BUF_STATE_ERROR;
|
buf->state = ISP_BUF_STATE_ERROR;
|
||||||
wake_up(&buf->wait);
|
wake_up(&buf->wait);
|
||||||
|
spin_unlock_irqrestore(&video->irqlock, flags);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
empty = list_empty(&video->dmaqueue);
|
empty = list_empty(&video->dmaqueue);
|
||||||
list_add_tail(&buffer->buffer.irqlist, &video->dmaqueue);
|
list_add_tail(&buffer->buffer.irqlist, &video->dmaqueue);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&video->irqlock, flags);
|
||||||
|
|
||||||
if (empty) {
|
if (empty) {
|
||||||
if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
||||||
state = ISP_PIPELINE_QUEUE_OUTPUT;
|
state = ISP_PIPELINE_QUEUE_OUTPUT;
|
||||||
|
@ -445,16 +450,16 @@ struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
|
|
||||||
spin_lock_irqsave(&queue->irqlock, flags);
|
spin_lock_irqsave(&video->irqlock, flags);
|
||||||
if (WARN_ON(list_empty(&video->dmaqueue))) {
|
if (WARN_ON(list_empty(&video->dmaqueue))) {
|
||||||
spin_unlock_irqrestore(&queue->irqlock, flags);
|
spin_unlock_irqrestore(&video->irqlock, flags);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = list_first_entry(&video->dmaqueue, struct isp_video_buffer,
|
buf = list_first_entry(&video->dmaqueue, struct isp_video_buffer,
|
||||||
irqlist);
|
irqlist);
|
||||||
list_del(&buf->irqlist);
|
list_del(&buf->irqlist);
|
||||||
spin_unlock_irqrestore(&queue->irqlock, flags);
|
spin_unlock_irqrestore(&video->irqlock, flags);
|
||||||
|
|
||||||
buf->vbuf.bytesused = vfh->format.fmt.pix.sizeimage;
|
buf->vbuf.bytesused = vfh->format.fmt.pix.sizeimage;
|
||||||
|
|
||||||
|
@ -520,10 +525,9 @@ struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video)
|
||||||
*/
|
*/
|
||||||
void omap3isp_video_cancel_stream(struct isp_video *video)
|
void omap3isp_video_cancel_stream(struct isp_video *video)
|
||||||
{
|
{
|
||||||
struct isp_video_queue *queue = video->queue;
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(&queue->irqlock, flags);
|
spin_lock_irqsave(&video->irqlock, flags);
|
||||||
|
|
||||||
while (!list_empty(&video->dmaqueue)) {
|
while (!list_empty(&video->dmaqueue)) {
|
||||||
struct isp_video_buffer *buf;
|
struct isp_video_buffer *buf;
|
||||||
|
@ -538,7 +542,7 @@ void omap3isp_video_cancel_stream(struct isp_video *video)
|
||||||
|
|
||||||
video->error = true;
|
video->error = true;
|
||||||
|
|
||||||
spin_unlock_irqrestore(&queue->irqlock, flags);
|
spin_unlock_irqrestore(&video->irqlock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1039,10 +1043,10 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
|
||||||
ISP_PIPELINE_STREAM_CONTINUOUS);
|
ISP_PIPELINE_STREAM_CONTINUOUS);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_set_stream;
|
goto err_set_stream;
|
||||||
spin_lock_irqsave(&video->queue->irqlock, flags);
|
spin_lock_irqsave(&video->irqlock, flags);
|
||||||
if (list_empty(&video->dmaqueue))
|
if (list_empty(&video->dmaqueue))
|
||||||
video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN;
|
video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN;
|
||||||
spin_unlock_irqrestore(&video->queue->irqlock, flags);
|
spin_unlock_irqrestore(&video->irqlock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
video->streaming = 1;
|
video->streaming = 1;
|
||||||
|
@ -1324,6 +1328,7 @@ int omap3isp_video_init(struct isp_video *video, const char *name)
|
||||||
spin_lock_init(&video->pipe.lock);
|
spin_lock_init(&video->pipe.lock);
|
||||||
mutex_init(&video->stream_lock);
|
mutex_init(&video->stream_lock);
|
||||||
mutex_init(&video->queue_lock);
|
mutex_init(&video->queue_lock);
|
||||||
|
spin_lock_init(&video->irqlock);
|
||||||
|
|
||||||
/* Initialize the video device. */
|
/* Initialize the video device. */
|
||||||
if (video->ops == NULL)
|
if (video->ops == NULL)
|
||||||
|
|
|
@ -183,6 +183,7 @@ struct isp_video {
|
||||||
/* Video buffers queue */
|
/* Video buffers queue */
|
||||||
struct isp_video_queue *queue;
|
struct isp_video_queue *queue;
|
||||||
struct mutex queue_lock; /* protects the queue */
|
struct mutex queue_lock; /* protects the queue */
|
||||||
|
spinlock_t irqlock; /* protects dmaqueue */
|
||||||
struct list_head dmaqueue;
|
struct list_head dmaqueue;
|
||||||
enum isp_video_dmaqueue_flags dmaqueue_flags;
|
enum isp_video_dmaqueue_flags dmaqueue_flags;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue