aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2008-11-16 18:18:05 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-12-30 06:38:08 -0500
commitf576ceefb481e5617ecfb77e3a05b3d26dbf2f92 (patch)
treed85b78c6ee7c5a4f52d6b8d6bcba87d00be8d0b0 /drivers
parent18b5dc2ed7f0ede825dd1f93fefc7a61aba866e3 (diff)
V4L/DVB (9722): cx18: Convert per stream queue spinlocks into mutexes
Convert the per stream queue spinlocks into mutexes. All queue manipulation happens via the work queue or system calls into the driver, and not in an interrupt context. This reduces the amout of time the cx18 driver keeps interrupts disabled. Signed-off-by: Andy Walls <awalls@radix.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/cx18/cx18-driver.h2
-rw-r--r--drivers/media/video/cx18/cx18-queue.c23
-rw-r--r--drivers/media/video/cx18/cx18-streams.c2
3 files changed, 11 insertions, 16 deletions
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index f8929eb72ad..041fa660a7c 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -271,7 +271,7 @@ struct cx18_stream {
271 unsigned mdl_offset; 271 unsigned mdl_offset;
272 272
273 u32 id; 273 u32 id;
274 spinlock_t qlock; /* locks access to the queues */ 274 struct mutex qlock; /* locks access to the queues */
275 unsigned long s_flags; /* status flags, see above */ 275 unsigned long s_flags; /* status flags, see above */
276 int dma; /* can be PCI_DMA_TODEVICE, 276 int dma; /* can be PCI_DMA_TODEVICE,
277 PCI_DMA_FROMDEVICE or 277 PCI_DMA_FROMDEVICE or
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
index c5a81aed61b..5a383940363 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -44,34 +44,31 @@ void cx18_queue_init(struct cx18_queue *q)
44void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, 44void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
45 struct cx18_queue *q) 45 struct cx18_queue *q)
46{ 46{
47 unsigned long flags = 0;
48
49 /* clear the buffer if it is going to be enqueued to the free queue */ 47 /* clear the buffer if it is going to be enqueued to the free queue */
50 if (q == &s->q_free) { 48 if (q == &s->q_free) {
51 buf->bytesused = 0; 49 buf->bytesused = 0;
52 buf->readpos = 0; 50 buf->readpos = 0;
53 buf->b_flags = 0; 51 buf->b_flags = 0;
54 } 52 }
55 spin_lock_irqsave(&s->qlock, flags); 53 mutex_lock(&s->qlock);
56 list_add_tail(&buf->list, &q->list); 54 list_add_tail(&buf->list, &q->list);
57 atomic_inc(&q->buffers); 55 atomic_inc(&q->buffers);
58 q->bytesused += buf->bytesused - buf->readpos; 56 q->bytesused += buf->bytesused - buf->readpos;
59 spin_unlock_irqrestore(&s->qlock, flags); 57 mutex_unlock(&s->qlock);
60} 58}
61 59
62struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q) 60struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q)
63{ 61{
64 struct cx18_buffer *buf = NULL; 62 struct cx18_buffer *buf = NULL;
65 unsigned long flags = 0;
66 63
67 spin_lock_irqsave(&s->qlock, flags); 64 mutex_lock(&s->qlock);
68 if (!list_empty(&q->list)) { 65 if (!list_empty(&q->list)) {
69 buf = list_entry(q->list.next, struct cx18_buffer, list); 66 buf = list_entry(q->list.next, struct cx18_buffer, list);
70 list_del_init(q->list.next); 67 list_del_init(q->list.next);
71 atomic_dec(&q->buffers); 68 atomic_dec(&q->buffers);
72 q->bytesused -= buf->bytesused - buf->readpos; 69 q->bytesused -= buf->bytesused - buf->readpos;
73 } 70 }
74 spin_unlock_irqrestore(&s->qlock, flags); 71 mutex_unlock(&s->qlock);
75 return buf; 72 return buf;
76} 73}
77 74
@@ -80,9 +77,8 @@ struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id,
80{ 77{
81 struct cx18 *cx = s->cx; 78 struct cx18 *cx = s->cx;
82 struct list_head *p; 79 struct list_head *p;
83 unsigned long flags = 0;
84 80
85 spin_lock_irqsave(&s->qlock, flags); 81 mutex_lock(&s->qlock);
86 list_for_each(p, &s->q_free.list) { 82 list_for_each(p, &s->q_free.list) {
87 struct cx18_buffer *buf = 83 struct cx18_buffer *buf =
88 list_entry(p, struct cx18_buffer, list); 84 list_entry(p, struct cx18_buffer, list);
@@ -102,10 +98,10 @@ struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id,
102 list_move_tail(&buf->list, &s->q_full.list); 98 list_move_tail(&buf->list, &s->q_full.list);
103 } 99 }
104 100
105 spin_unlock_irqrestore(&s->qlock, flags); 101 mutex_unlock(&s->qlock);
106 return buf; 102 return buf;
107 } 103 }
108 spin_unlock_irqrestore(&s->qlock, flags); 104 mutex_unlock(&s->qlock);
109 CX18_ERR("Cannot find buffer %d for stream %s\n", id, s->name); 105 CX18_ERR("Cannot find buffer %d for stream %s\n", id, s->name);
110 return NULL; 106 return NULL;
111} 107}
@@ -113,13 +109,12 @@ struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id,
113/* Move all buffers of a queue to q_free, while flushing the buffers */ 109/* Move all buffers of a queue to q_free, while flushing the buffers */
114static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q) 110static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q)
115{ 111{
116 unsigned long flags;
117 struct cx18_buffer *buf; 112 struct cx18_buffer *buf;
118 113
119 if (q == &s->q_free) 114 if (q == &s->q_free)
120 return; 115 return;
121 116
122 spin_lock_irqsave(&s->qlock, flags); 117 mutex_lock(&s->qlock);
123 while (!list_empty(&q->list)) { 118 while (!list_empty(&q->list)) {
124 buf = list_entry(q->list.next, struct cx18_buffer, list); 119 buf = list_entry(q->list.next, struct cx18_buffer, list);
125 list_move_tail(q->list.next, &s->q_free.list); 120 list_move_tail(q->list.next, &s->q_free.list);
@@ -127,7 +122,7 @@ static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q)
127 atomic_inc(&s->q_free.buffers); 122 atomic_inc(&s->q_free.buffers);
128 } 123 }
129 cx18_queue_init(q); 124 cx18_queue_init(q);
130 spin_unlock_irqrestore(&s->qlock, flags); 125 mutex_unlock(&s->qlock);
131} 126}
132 127
133void cx18_flush_queues(struct cx18_stream *s) 128void cx18_flush_queues(struct cx18_stream *s)
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index e6d808f7cc8..e218e4d0ebf 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -132,7 +132,7 @@ static void cx18_stream_init(struct cx18 *cx, int type)
132 s->buffers = 63; 132 s->buffers = 63;
133 s->buf_size = (max_size / s->buffers) & ~0xfff; 133 s->buf_size = (max_size / s->buffers) & ~0xfff;
134 } 134 }
135 spin_lock_init(&s->qlock); 135 mutex_init(&s->qlock);
136 init_waitqueue_head(&s->waitq); 136 init_waitqueue_head(&s->waitq);
137 s->id = -1; 137 s->id = -1;
138 cx18_queue_init(&s->q_free); 138 cx18_queue_init(&s->q_free);