diff options
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/ivtv/ivtv-driver.c | 11 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-streams.c | 100 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-streams.h | 1 |
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 | ||
169 | static int ivtv_reg_dev(struct ivtv *itv, int type) | 169 | static 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", | 226 | int 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 | |||
251 | static 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 */ |
266 | int ivtv_streams_setup(struct ivtv *itv) | 294 | int 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 | ||
24 | int ivtv_streams_setup(struct ivtv *itv); | 24 | int ivtv_streams_setup(struct ivtv *itv); |
25 | int ivtv_streams_register(struct ivtv *itv); | ||
25 | void ivtv_streams_cleanup(struct ivtv *itv); | 26 | void ivtv_streams_cleanup(struct ivtv *itv); |
26 | 27 | ||
27 | /* Capture related */ | 28 | /* Capture related */ |