diff options
-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 fd7a932..6d2dd87 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, IVTV_DEBUG_INFO("base addr: 0x%08x\n", itv->base_addr); - mutex_lock(&itv->serialize_lock); - /* PCI Device Setup */ if ((retval = ivtv_setup_pci(itv, dev, pci_id)) != 0) { if (retval == -EIO) @@ -1064,7 +1062,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev, IVTV_DEBUG_INFO("activating i2c...\n"); if (init_ivtv_i2c(itv)) { IVTV_ERR("Could not initialize i2c\n"); - goto free_irq; + goto free_io; } IVTV_DEBUG_INFO("Active card count: %d.\n", ivtv_cards_active); @@ -1176,7 +1174,11 @@ static int __devinit ivtv_probe(struct pci_dev *dev, IVTV_ERR("Failed to register irq %d\n", retval); goto free_streams; } - mutex_unlock(&itv->serialize_lock); + retval = ivtv_streams_register(itv); + if (retval) { + IVTV_ERR("Error %d registering devices\n", retval); + goto free_irq; + } IVTV_INFO("Initialized card #%d: %s\n", itv->num, itv->card_name); return 0; @@ -1195,7 +1197,6 @@ static int __devinit ivtv_probe(struct pci_dev *dev, release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); free_workqueue: destroy_workqueue(itv->irq_work_queues); - mutex_unlock(&itv->serialize_lock); err: if (retval == 0) retval = -ENODEV; diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index ff4cb16..6c954b3 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) ivtv_queue_init(&s->q_io); } -static int ivtv_reg_dev(struct ivtv *itv, int type) +static int ivtv_prep_dev(struct ivtv *itv, int type) { struct ivtv_stream *s = &itv->streams[type]; - int vfl_type = ivtv_stream_info[type].vfl_type; int minor_offset = ivtv_stream_info[type].minor_offset; int minor; @@ -187,15 +186,12 @@ static int ivtv_reg_dev(struct ivtv *itv, int type) if (type >= IVTV_DEC_STREAM_TYPE_MPG && !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) return 0; - if (minor_offset >= 0) - /* card number + user defined offset + device offset */ - minor = itv->num + ivtv_first_minor + minor_offset; - else - minor = -1; + /* card number + user defined offset + device offset */ + minor = itv->num + ivtv_first_minor + minor_offset; /* User explicitly selected 0 buffers for these streams, so don't create them. */ - if (minor >= 0 && ivtv_stream_info[type].dma != PCI_DMA_NONE && + if (ivtv_stream_info[type].dma != PCI_DMA_NONE && itv->options.kilobytes[type] == 0) { IVTV_INFO("Disabled %s device\n", ivtv_stream_info[type].name); return 0; @@ -223,21 +219,53 @@ static int ivtv_reg_dev(struct ivtv *itv, int type) s->v4l2dev->fops = ivtv_stream_info[type].fops; s->v4l2dev->release = video_device_release; - if (minor >= 0) { - /* Register device. First try the desired minor, then any free one. */ - if (video_register_device(s->v4l2dev, vfl_type, minor) && - video_register_device(s->v4l2dev, vfl_type, -1)) { - IVTV_ERR("Couldn't register v4l2 device for %s minor %d\n", - s->name, minor); - video_device_release(s->v4l2dev); - s->v4l2dev = NULL; - return -ENOMEM; - } + return 0; +} + +/* Initialize v4l2 variables and prepare v4l2 devices */ +int ivtv_streams_setup(struct ivtv *itv) +{ + int type; + + /* Setup V4L2 Devices */ + for (type = 0; type < IVTV_MAX_STREAMS; type++) { + /* Prepare device */ + if (ivtv_prep_dev(itv, type)) + break; + + if (itv->streams[type].v4l2dev == NULL) + continue; + + /* Allocate Stream */ + if (ivtv_stream_alloc(&itv->streams[type])) + break; } - else { - /* Don't register a 'hidden' stream (OSD) */ - IVTV_INFO("Created framebuffer stream for %s\n", s->name); + if (type == IVTV_MAX_STREAMS) return 0; + + /* One or more streams could not be initialized. Clean 'em all up. */ + ivtv_streams_cleanup(itv); + return -ENOMEM; +} + +static int ivtv_reg_dev(struct ivtv *itv, int type) +{ + struct ivtv_stream *s = &itv->streams[type]; + int vfl_type = ivtv_stream_info[type].vfl_type; + int minor; + + if (s->v4l2dev == NULL) + return 0; + + minor = s->v4l2dev->minor; + /* Register device. First try the desired minor, then any free one. */ + if (video_register_device(s->v4l2dev, vfl_type, minor) && + video_register_device(s->v4l2dev, vfl_type, -1)) { + IVTV_ERR("Couldn't register v4l2 device for %s minor %d\n", + s->name, minor); + video_device_release(s->v4l2dev); + s->v4l2dev = NULL; + return -ENOMEM; } switch (vfl_type) { @@ -262,27 +290,18 @@ static int ivtv_reg_dev(struct ivtv *itv, int type) return 0; } -/* Initialize v4l2 variables and register v4l2 devices */ -int ivtv_streams_setup(struct ivtv *itv) +/* Register v4l2 devices */ +int ivtv_streams_register(struct ivtv *itv) { int type; + int err = 0; - /* Setup V4L2 Devices */ - for (type = 0; type < IVTV_MAX_STREAMS; type++) { - /* Register Device */ - if (ivtv_reg_dev(itv, type)) - break; - - if (itv->streams[type].v4l2dev == NULL) - continue; + /* Register V4L2 devices */ + for (type = 0; type < IVTV_MAX_STREAMS; type++) + err |= ivtv_reg_dev(itv, type); - /* Allocate Stream */ - if (ivtv_stream_alloc(&itv->streams[type])) - break; - } - if (type == IVTV_MAX_STREAMS) { + if (err == 0) return 0; - } /* One or more streams could not be initialized. Clean 'em all up. */ ivtv_streams_cleanup(itv); @@ -303,11 +322,8 @@ void ivtv_streams_cleanup(struct ivtv *itv) continue; ivtv_stream_free(&itv->streams[type]); - /* Free Device */ - if (vdev->minor == -1) /* 'Hidden' never registered stream (OSD) */ - video_device_release(vdev); - else /* All others, just unregister. */ - video_unregister_device(vdev); + /* Unregister device */ + video_unregister_device(vdev); } } diff --git a/drivers/media/video/ivtv/ivtv-streams.h b/drivers/media/video/ivtv/ivtv-streams.h index 8f5f5b1..3d76a41 100644 --- a/drivers/media/video/ivtv/ivtv-streams.h +++ b/drivers/media/video/ivtv/ivtv-streams.h @@ -22,6 +22,7 @@ #define IVTV_STREAMS_H int ivtv_streams_setup(struct ivtv *itv); +int ivtv_streams_register(struct ivtv *itv); void ivtv_streams_cleanup(struct ivtv *itv); /* Capture related */ |