aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c11
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c100
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.h1
3 files changed, 65 insertions, 47 deletions
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index fd7a932e1d33..6d2dd8764f81 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -1003,8 +1003,6 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
1003 1003
1004 IVTV_DEBUG_INFO("base addr: 0x%08x\n", itv->base_addr); 1004 IVTV_DEBUG_INFO("base addr: 0x%08x\n", itv->base_addr);
1005 1005
1006 mutex_lock(&itv->serialize_lock);
1007
1008 /* PCI Device Setup */ 1006 /* PCI Device Setup */
1009 if ((retval = ivtv_setup_pci(itv, dev, pci_id)) != 0) { 1007 if ((retval = ivtv_setup_pci(itv, dev, pci_id)) != 0) {
1010 if (retval == -EIO) 1008 if (retval == -EIO)
@@ -1064,7 +1062,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
1064 IVTV_DEBUG_INFO("activating i2c...\n"); 1062 IVTV_DEBUG_INFO("activating i2c...\n");
1065 if (init_ivtv_i2c(itv)) { 1063 if (init_ivtv_i2c(itv)) {
1066 IVTV_ERR("Could not initialize i2c\n"); 1064 IVTV_ERR("Could not initialize i2c\n");
1067 goto free_irq; 1065 goto free_io;
1068 } 1066 }
1069 1067
1070 IVTV_DEBUG_INFO("Active card count: %d.\n", ivtv_cards_active); 1068 IVTV_DEBUG_INFO("Active card count: %d.\n", ivtv_cards_active);
@@ -1176,7 +1174,11 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
1176 IVTV_ERR("Failed to register irq %d\n", retval); 1174 IVTV_ERR("Failed to register irq %d\n", retval);
1177 goto free_streams; 1175 goto free_streams;
1178 } 1176 }
1179 mutex_unlock(&itv->serialize_lock); 1177 retval = ivtv_streams_register(itv);
1178 if (retval) {
1179 IVTV_ERR("Error %d registering devices\n", retval);
1180 goto free_irq;
1181 }
1180 IVTV_INFO("Initialized card #%d: %s\n", itv->num, itv->card_name); 1182 IVTV_INFO("Initialized card #%d: %s\n", itv->num, itv->card_name);
1181 return 0; 1183 return 0;
1182 1184
@@ -1195,7 +1197,6 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
1195 release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); 1197 release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
1196 free_workqueue: 1198 free_workqueue:
1197 destroy_workqueue(itv->irq_work_queues); 1199 destroy_workqueue(itv->irq_work_queues);
1198 mutex_unlock(&itv->serialize_lock);
1199 err: 1200 err:
1200 if (retval == 0) 1201 if (retval == 0)
1201 retval = -ENODEV; 1202 retval = -ENODEV;
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index ff4cb16a3439..6c954b36ee88 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -166,10 +166,9 @@ static void ivtv_stream_init(struct ivtv *itv, int type)
166 ivtv_queue_init(&s->q_io); 166 ivtv_queue_init(&s->q_io);
167} 167}
168 168
169static int ivtv_reg_dev(struct ivtv *itv, int type) 169static int ivtv_prep_dev(struct ivtv *itv, int type)
170{ 170{
171 struct ivtv_stream *s = &itv->streams[type]; 171 struct ivtv_stream *s = &itv->streams[type];
172 int vfl_type = ivtv_stream_info[type].vfl_type;
173 int minor_offset = ivtv_stream_info[type].minor_offset; 172 int minor_offset = ivtv_stream_info[type].minor_offset;
174 int minor; 173 int minor;
175 174
@@ -187,15 +186,12 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
187 if (type >= IVTV_DEC_STREAM_TYPE_MPG && !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) 186 if (type >= IVTV_DEC_STREAM_TYPE_MPG && !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
188 return 0; 187 return 0;
189 188
190 if (minor_offset >= 0) 189 /* card number + user defined offset + device offset */
191 /* card number + user defined offset + device offset */ 190 minor = itv->num + ivtv_first_minor + minor_offset;
192 minor = itv->num + ivtv_first_minor + minor_offset;
193 else
194 minor = -1;
195 191
196 /* User explicitly selected 0 buffers for these streams, so don't 192 /* User explicitly selected 0 buffers for these streams, so don't
197 create them. */ 193 create them. */
198 if (minor >= 0 && ivtv_stream_info[type].dma != PCI_DMA_NONE && 194 if (ivtv_stream_info[type].dma != PCI_DMA_NONE &&
199 itv->options.kilobytes[type] == 0) { 195 itv->options.kilobytes[type] == 0) {
200 IVTV_INFO("Disabled %s device\n", ivtv_stream_info[type].name); 196 IVTV_INFO("Disabled %s device\n", ivtv_stream_info[type].name);
201 return 0; 197 return 0;
@@ -223,21 +219,53 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
223 s->v4l2dev->fops = ivtv_stream_info[type].fops; 219 s->v4l2dev->fops = ivtv_stream_info[type].fops;
224 s->v4l2dev->release = video_device_release; 220 s->v4l2dev->release = video_device_release;
225 221
226 if (minor >= 0) { 222 return 0;
227 /* Register device. First try the desired minor, then any free one. */ 223}
228 if (video_register_device(s->v4l2dev, vfl_type, minor) && 224
229 video_register_device(s->v4l2dev, vfl_type, -1)) { 225/* Initialize v4l2 variables and prepare v4l2 devices */
230 IVTV_ERR("Couldn't register v4l2 device for %s minor %d\n", 226int ivtv_streams_setup(struct ivtv *itv)
231 s->name, minor); 227{
232 video_device_release(s->v4l2dev); 228 int type;
233 s->v4l2dev = NULL; 229
234 return -ENOMEM; 230 /* Setup V4L2 Devices */
235 } 231 for (type = 0; type < IVTV_MAX_STREAMS; type++) {
232 /* Prepare device */
233 if (ivtv_prep_dev(itv, type))
234 break;
235
236 if (itv->streams[type].v4l2dev == NULL)
237 continue;
238
239 /* Allocate Stream */
240 if (ivtv_stream_alloc(&itv->streams[type]))
241 break;
236 } 242 }
237 else { 243 if (type == IVTV_MAX_STREAMS)
238 /* Don't register a 'hidden' stream (OSD) */
239 IVTV_INFO("Created framebuffer stream for %s\n", s->name);
240 return 0; 244 return 0;
245
246 /* One or more streams could not be initialized. Clean 'em all up. */
247 ivtv_streams_cleanup(itv);
248 return -ENOMEM;
249}
250
251static int ivtv_reg_dev(struct ivtv *itv, int type)
252{
253 struct ivtv_stream *s = &itv->streams[type];
254 int vfl_type = ivtv_stream_info[type].vfl_type;
255 int minor;
256
257 if (s->v4l2dev == NULL)
258 return 0;
259
260 minor = s->v4l2dev->minor;
261 /* Register device. First try the desired minor, then any free one. */
262 if (video_register_device(s->v4l2dev, vfl_type, minor) &&
263 video_register_device(s->v4l2dev, vfl_type, -1)) {
264 IVTV_ERR("Couldn't register v4l2 device for %s minor %d\n",
265 s->name, minor);
266 video_device_release(s->v4l2dev);
267 s->v4l2dev = NULL;
268 return -ENOMEM;
241 } 269 }
242 270
243 switch (vfl_type) { 271 switch (vfl_type) {
@@ -262,27 +290,18 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
262 return 0; 290 return 0;
263} 291}
264 292
265/* Initialize v4l2 variables and register v4l2 devices */ 293/* Register v4l2 devices */
266int ivtv_streams_setup(struct ivtv *itv) 294int ivtv_streams_register(struct ivtv *itv)
267{ 295{
268 int type; 296 int type;
297 int err = 0;
269 298
270 /* Setup V4L2 Devices */ 299 /* Register V4L2 devices */
271 for (type = 0; type < IVTV_MAX_STREAMS; type++) { 300 for (type = 0; type < IVTV_MAX_STREAMS; type++)
272 /* Register Device */ 301 err |= ivtv_reg_dev(itv, type);
273 if (ivtv_reg_dev(itv, type))
274 break;
275
276 if (itv->streams[type].v4l2dev == NULL)
277 continue;
278 302
279 /* Allocate Stream */ 303 if (err == 0)
280 if (ivtv_stream_alloc(&itv->streams[type]))
281 break;
282 }
283 if (type == IVTV_MAX_STREAMS) {
284 return 0; 304 return 0;
285 }
286 305
287 /* One or more streams could not be initialized. Clean 'em all up. */ 306 /* One or more streams could not be initialized. Clean 'em all up. */
288 ivtv_streams_cleanup(itv); 307 ivtv_streams_cleanup(itv);
@@ -303,11 +322,8 @@ void ivtv_streams_cleanup(struct ivtv *itv)
303 continue; 322 continue;
304 323
305 ivtv_stream_free(&itv->streams[type]); 324 ivtv_stream_free(&itv->streams[type]);
306 /* Free Device */ 325 /* Unregister device */
307 if (vdev->minor == -1) /* 'Hidden' never registered stream (OSD) */ 326 video_unregister_device(vdev);
308 video_device_release(vdev);
309 else /* All others, just unregister. */
310 video_unregister_device(vdev);
311 } 327 }
312} 328}
313 329
diff --git a/drivers/media/video/ivtv/ivtv-streams.h b/drivers/media/video/ivtv/ivtv-streams.h
index 8f5f5b1c7c89..3d76a415fbd8 100644
--- a/drivers/media/video/ivtv/ivtv-streams.h
+++ b/drivers/media/video/ivtv/ivtv-streams.h
@@ -22,6 +22,7 @@
22#define IVTV_STREAMS_H 22#define IVTV_STREAMS_H
23 23
24int ivtv_streams_setup(struct ivtv *itv); 24int ivtv_streams_setup(struct ivtv *itv);
25int ivtv_streams_register(struct ivtv *itv);
25void ivtv_streams_cleanup(struct ivtv *itv); 26void ivtv_streams_cleanup(struct ivtv *itv);
26 27
27/* Capture related */ 28/* Capture related */