[media] ivtv: embed video_device
authorHans Verkuil <hans.verkuil@cisco.com>
Mon, 9 Mar 2015 16:33:55 +0000 (13:33 -0300)
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>
Fri, 3 Apr 2015 01:34:55 +0000 (22:34 -0300)
Embed the video_device struct to simplify the error handling and in
order to (eventually) get rid of video_device_alloc/release.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Cc: Andy Walls <awalls@md.metrocast.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
drivers/media/pci/ivtv/ivtv-alsa-main.c
drivers/media/pci/ivtv/ivtv-alsa-pcm.c
drivers/media/pci/ivtv/ivtv-driver.c
drivers/media/pci/ivtv/ivtv-driver.h
drivers/media/pci/ivtv/ivtv-fileops.c
drivers/media/pci/ivtv/ivtv-ioctl.c
drivers/media/pci/ivtv/ivtv-irq.c
drivers/media/pci/ivtv/ivtv-streams.c
drivers/media/pci/ivtv/ivtv-streams.h

index 39b52929755aca482839c01f46f4fd2251183bd6..41fa21534edf1ae2de7f84924fe2606dbbc83fbf 100644 (file)
@@ -224,7 +224,7 @@ static int ivtv_alsa_load(struct ivtv *itv)
        }
 
        s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM];
-       if (s->vdev == NULL) {
+       if (s->vdev.v4l2_dev == NULL) {
                IVTV_DEBUG_ALSA_INFO("%s: PCM stream for card is disabled - "
                                     "skipping\n", __func__);
                return 0;
index 7bf9cbca4fa64fe3e63c3d17ea7432e661069e85..f198b9826ed8d63d5c43e623ba096eea0d853de7 100644 (file)
@@ -167,7 +167,7 @@ static int snd_ivtv_pcm_capture_open(struct snd_pcm_substream *substream)
 
        s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM];
 
-       v4l2_fh_init(&item.fh, s->vdev);
+       v4l2_fh_init(&item.fh, &s->vdev);
        item.itv = itv;
        item.type = s->type;
 
index 802642d266438ffaaf6f136a30e141ffb452810e..c2e60b4f292d1d8d9791b5c44b0fa76c0ffd854b 100644 (file)
@@ -1284,7 +1284,7 @@ static int ivtv_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
        return 0;
 
 free_streams:
-       ivtv_streams_cleanup(itv, 1);
+       ivtv_streams_cleanup(itv);
 free_irq:
        free_irq(itv->pdev->irq, (void *)itv);
 free_i2c:
@@ -1444,7 +1444,7 @@ static void ivtv_remove(struct pci_dev *pdev)
        flush_kthread_worker(&itv->irq_worker);
        kthread_stop(itv->irq_worker_task);
 
-       ivtv_streams_cleanup(itv, 1);
+       ivtv_streams_cleanup(itv);
        ivtv_udma_free(itv);
 
        v4l2_ctrl_handler_free(&itv->cxhdl.hdl);
index bc309f42c8ed29bb2782cb70521250b6f809c7d4..e8b6c7ad2ba9bcfc5ddf620d33c58996db63e993 100644 (file)
@@ -327,7 +327,7 @@ struct ivtv;                                /* forward reference */
 struct ivtv_stream {
        /* These first four fields are always set, even if the stream
           is not actually created. */
-       struct video_device *vdev;      /* NULL when stream not created */
+       struct video_device vdev;       /* vdev.v4l2_dev is NULL if there is no device */
        struct ivtv *itv;               /* for ease of use */
        const char *name;               /* name of the stream */
        int type;                       /* stream type */
index e5ff6277ca854704143398b43e585af5c6204dc5..605d280d8a5f00f2f142498532eb2c53f40be8fa 100644 (file)
@@ -995,7 +995,7 @@ static int ivtv_open(struct file *filp)
                IVTV_DEBUG_WARN("nomem on v4l2 open\n");
                return -ENOMEM;
        }
-       v4l2_fh_init(&item->fh, s->vdev);
+       v4l2_fh_init(&item->fh, &s->vdev);
        item->itv = itv;
        item->type = s->type;
 
index 4d8ee18c3feb17978d048c3bbec8c5e4efe79763..fa875655ede64109353b742336adbce84261e333 100644 (file)
@@ -987,7 +987,7 @@ int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
        else
                std = V4L2_STD_ALL;
        for (i = 0; i <= IVTV_ENC_STREAM_TYPE_VBI; i++)
-               itv->streams[i].vdev->tvnorms = std;
+               itv->streams[i].vdev.tvnorms = std;
 
        /* prevent others from messing with the streams until
           we're finished changing inputs. */
@@ -1038,7 +1038,7 @@ static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *
        struct ivtv *itv = fh2id(fh)->itv;
        struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
 
-       if (s->vdev->vfl_dir)
+       if (s->vdev.vfl_dir)
                return -ENOTTY;
        if (vf->tuner != 0)
                return -EINVAL;
@@ -1052,7 +1052,7 @@ int ivtv_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *v
        struct ivtv *itv = fh2id(fh)->itv;
        struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
 
-       if (s->vdev->vfl_dir)
+       if (s->vdev.vfl_dir)
                return -ENOTTY;
        if (vf->tuner != 0)
                return -EINVAL;
@@ -1547,7 +1547,7 @@ static int ivtv_log_status(struct file *file, void *fh)
        for (i = 0; i < IVTV_MAX_STREAMS; i++) {
                struct ivtv_stream *s = &itv->streams[i];
 
-               if (s->vdev == NULL || s->buffers == 0)
+               if (s->vdev.v4l2_dev == NULL || s->buffers == 0)
                        continue;
                IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
                                (s->buffers - s->q_free.buffers) * 100 / s->buffers,
index e7d701777e53fe44af8426685c7aaf57996c90ab..36ca2d67c812189ffe9f1cc3b0a85c1251e4cbf3 100644 (file)
@@ -75,7 +75,7 @@ static void ivtv_pio_work_handler(struct ivtv *itv)
 
        IVTV_DEBUG_HI_DMA("ivtv_pio_work_handler\n");
        if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS ||
-                       s->vdev == NULL || !ivtv_use_pio(s)) {
+                       s->vdev.v4l2_dev == NULL || !ivtv_use_pio(s)) {
                itv->cur_pio_stream = -1;
                /* trigger PIO complete user interrupt */
                write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44);
@@ -132,7 +132,7 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA
        int rc;
 
        /* sanity checks */
-       if (s->vdev == NULL) {
+       if (s->vdev.v4l2_dev == NULL) {
                IVTV_DEBUG_WARN("Stream %s not started\n", s->name);
                return -1;
        }
@@ -890,8 +890,8 @@ static void ivtv_irq_vsync(struct ivtv *itv)
                        if (s)
                                wake_up(&s->waitq);
                }
-               if (s && s->vdev)
-                       v4l2_event_queue(s->vdev, frame ? &evtop : &evbottom);
+               if (s && s->vdev.v4l2_dev)
+                       v4l2_event_queue(&s->vdev, frame ? &evtop : &evbottom);
                wake_up(&itv->vsync_waitq);
 
                /* Send VBI to saa7127 */
index f0a1cc472313cc5c42292c59900539f2e43494f1..cfb61f23d8ed64e7a10411430e40b77d128445d7 100644 (file)
@@ -159,11 +159,9 @@ static struct {
 static void ivtv_stream_init(struct ivtv *itv, int type)
 {
        struct ivtv_stream *s = &itv->streams[type];
-       struct video_device *vdev = s->vdev;
 
        /* we need to keep vdev, so restore it afterwards */
        memset(s, 0, sizeof(*s));
-       s->vdev = vdev;
 
        /* initialize ivtv_stream fields */
        s->itv = itv;
@@ -194,10 +192,10 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
        int num_offset = ivtv_stream_info[type].num_offset;
        int num = itv->instance + ivtv_first_minor + num_offset;
 
-       /* These four fields are always initialized. If vdev == NULL, then
+       /* These four fields are always initialized. If vdev.v4l2_dev == NULL, then
           this stream is not in use. In that case no other fields but these
           four can be used. */
-       s->vdev = NULL;
+       s->vdev.v4l2_dev = NULL;
        s->itv = itv;
        s->type = type;
        s->name = ivtv_stream_info[type].name;
@@ -218,40 +216,33 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
 
        ivtv_stream_init(itv, type);
 
-       /* allocate and initialize the v4l2 video device structure */
-       s->vdev = video_device_alloc();
-       if (s->vdev == NULL) {
-               IVTV_ERR("Couldn't allocate v4l2 video_device for %s\n", s->name);
-               return -ENOMEM;
-       }
-
-       snprintf(s->vdev->name, sizeof(s->vdev->name), "%s %s",
+       snprintf(s->vdev.name, sizeof(s->vdev.name), "%s %s",
                        itv->v4l2_dev.name, s->name);
 
-       s->vdev->num = num;
-       s->vdev->v4l2_dev = &itv->v4l2_dev;
+       s->vdev.num = num;
+       s->vdev.v4l2_dev = &itv->v4l2_dev;
        if (ivtv_stream_info[type].v4l2_caps &
                        (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_SLICED_VBI_OUTPUT))
-               s->vdev->vfl_dir = VFL_DIR_TX;
-       s->vdev->fops = ivtv_stream_info[type].fops;
-       s->vdev->ctrl_handler = itv->v4l2_dev.ctrl_handler;
-       s->vdev->release = video_device_release;
-       s->vdev->tvnorms = V4L2_STD_ALL;
-       s->vdev->lock = &itv->serialize_lock;
+               s->vdev.vfl_dir = VFL_DIR_TX;
+       s->vdev.fops = ivtv_stream_info[type].fops;
+       s->vdev.ctrl_handler = itv->v4l2_dev.ctrl_handler;
+       s->vdev.release = video_device_release_empty;
+       s->vdev.tvnorms = V4L2_STD_ALL;
+       s->vdev.lock = &itv->serialize_lock;
        if (s->type == IVTV_DEC_STREAM_TYPE_VBI) {
-               v4l2_disable_ioctl(s->vdev, VIDIOC_S_AUDIO);
-               v4l2_disable_ioctl(s->vdev, VIDIOC_G_AUDIO);
-               v4l2_disable_ioctl(s->vdev, VIDIOC_ENUMAUDIO);
-               v4l2_disable_ioctl(s->vdev, VIDIOC_ENUMINPUT);
-               v4l2_disable_ioctl(s->vdev, VIDIOC_S_INPUT);
-               v4l2_disable_ioctl(s->vdev, VIDIOC_G_INPUT);
-               v4l2_disable_ioctl(s->vdev, VIDIOC_S_FREQUENCY);
-               v4l2_disable_ioctl(s->vdev, VIDIOC_G_FREQUENCY);
-               v4l2_disable_ioctl(s->vdev, VIDIOC_S_TUNER);
-               v4l2_disable_ioctl(s->vdev, VIDIOC_G_TUNER);
-               v4l2_disable_ioctl(s->vdev, VIDIOC_S_STD);
+               v4l2_disable_ioctl(&s->vdev, VIDIOC_S_AUDIO);
+               v4l2_disable_ioctl(&s->vdev, VIDIOC_G_AUDIO);
+               v4l2_disable_ioctl(&s->vdev, VIDIOC_ENUMAUDIO);
+               v4l2_disable_ioctl(&s->vdev, VIDIOC_ENUMINPUT);
+               v4l2_disable_ioctl(&s->vdev, VIDIOC_S_INPUT);
+               v4l2_disable_ioctl(&s->vdev, VIDIOC_G_INPUT);
+               v4l2_disable_ioctl(&s->vdev, VIDIOC_S_FREQUENCY);
+               v4l2_disable_ioctl(&s->vdev, VIDIOC_G_FREQUENCY);
+               v4l2_disable_ioctl(&s->vdev, VIDIOC_S_TUNER);
+               v4l2_disable_ioctl(&s->vdev, VIDIOC_G_TUNER);
+               v4l2_disable_ioctl(&s->vdev, VIDIOC_S_STD);
        }
-       ivtv_set_funcs(s->vdev);
+       ivtv_set_funcs(&s->vdev);
        return 0;
 }
 
@@ -266,7 +257,7 @@ int ivtv_streams_setup(struct ivtv *itv)
                if (ivtv_prep_dev(itv, type))
                        break;
 
-               if (itv->streams[type].vdev == NULL)
+               if (itv->streams[type].vdev.v4l2_dev == NULL)
                        continue;
 
                /* Allocate Stream */
@@ -277,7 +268,7 @@ int ivtv_streams_setup(struct ivtv *itv)
                return 0;
 
        /* One or more streams could not be initialized. Clean 'em all up. */
-       ivtv_streams_cleanup(itv, 0);
+       ivtv_streams_cleanup(itv);
        return -ENOMEM;
 }
 
@@ -288,28 +279,26 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
        const char *name;
        int num;
 
-       if (s->vdev == NULL)
+       if (s->vdev.v4l2_dev == NULL)
                return 0;
 
-       num = s->vdev->num;
+       num = s->vdev.num;
        /* card number + user defined offset + device offset */
        if (type != IVTV_ENC_STREAM_TYPE_MPG) {
                struct ivtv_stream *s_mpg = &itv->streams[IVTV_ENC_STREAM_TYPE_MPG];
 
-               if (s_mpg->vdev)
-                       num = s_mpg->vdev->num + ivtv_stream_info[type].num_offset;
+               if (s_mpg->vdev.v4l2_dev)
+                       num = s_mpg->vdev.num + ivtv_stream_info[type].num_offset;
        }
-       video_set_drvdata(s->vdev, s);
+       video_set_drvdata(&s->vdev, s);
 
        /* Register device. First try the desired minor, then any free one. */
-       if (video_register_device_no_warn(s->vdev, vfl_type, num)) {
+       if (video_register_device_no_warn(&s->vdev, vfl_type, num)) {
                IVTV_ERR("Couldn't register v4l2 device for %s (device node number %d)\n",
                                s->name, num);
-               video_device_release(s->vdev);
-               s->vdev = NULL;
                return -ENOMEM;
        }
-       name = video_device_node_name(s->vdev);
+       name = video_device_node_name(&s->vdev);
 
        switch (vfl_type) {
        case VFL_TYPE_GRABBER:
@@ -346,29 +335,25 @@ int ivtv_streams_register(struct ivtv *itv)
                return 0;
 
        /* One or more streams could not be initialized. Clean 'em all up. */
-       ivtv_streams_cleanup(itv, 1);
+       ivtv_streams_cleanup(itv);
        return -ENOMEM;
 }
 
 /* Unregister v4l2 devices */
-void ivtv_streams_cleanup(struct ivtv *itv, int unregister)
+void ivtv_streams_cleanup(struct ivtv *itv)
 {
        int type;
 
        /* Teardown all streams */
        for (type = 0; type < IVTV_MAX_STREAMS; type++) {
-               struct video_device *vdev = itv->streams[type].vdev;
+               struct video_device *vdev = &itv->streams[type].vdev;
 
-               itv->streams[type].vdev = NULL;
-               if (vdev == NULL)
+               if (vdev->v4l2_dev == NULL)
                        continue;
 
+               video_unregister_device(vdev);
                ivtv_stream_free(&itv->streams[type]);
-               /* Unregister or release device */
-               if (unregister)
-                       video_unregister_device(vdev);
-               else
-                       video_device_release(vdev);
+               itv->streams[type].vdev.v4l2_dev = NULL;
        }
 }
 
@@ -492,7 +477,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
        int captype = 0, subtype = 0;
        int enable_passthrough = 0;
 
-       if (s->vdev == NULL)
+       if (s->vdev.v4l2_dev == NULL)
                return -EINVAL;
 
        IVTV_DEBUG_INFO("Start encoder stream %s\n", s->name);
@@ -661,7 +646,7 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
        u16 width;
        u16 height;
 
-       if (s->vdev == NULL)
+       if (s->vdev.v4l2_dev == NULL)
                return -EINVAL;
 
        IVTV_DEBUG_INFO("Setting some initial decoder settings\n");
@@ -723,7 +708,7 @@ int ivtv_start_v4l2_decode_stream(struct ivtv_stream *s, int gop_offset)
        struct ivtv *itv = s->itv;
        int rc;
 
-       if (s->vdev == NULL)
+       if (s->vdev.v4l2_dev == NULL)
                return -EINVAL;
 
        if (test_and_set_bit(IVTV_F_S_STREAMING, &s->s_flags))
@@ -778,7 +763,7 @@ void ivtv_stop_all_captures(struct ivtv *itv)
        for (i = IVTV_MAX_STREAMS - 1; i >= 0; i--) {
                struct ivtv_stream *s = &itv->streams[i];
 
-               if (s->vdev == NULL)
+               if (s->vdev.v4l2_dev == NULL)
                        continue;
                if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
                        ivtv_stop_v4l2_encode_stream(s, 0);
@@ -793,7 +778,7 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
        int cap_type;
        int stopmode;
 
-       if (s->vdev == NULL)
+       if (s->vdev.v4l2_dev == NULL)
                return -EINVAL;
 
        /* This function assumes that you are allowed to stop the capture
@@ -917,7 +902,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
        };
        struct ivtv *itv = s->itv;
 
-       if (s->vdev == NULL)
+       if (s->vdev.v4l2_dev == NULL)
                return -EINVAL;
 
        if (s->type != IVTV_DEC_STREAM_TYPE_YUV && s->type != IVTV_DEC_STREAM_TYPE_MPG)
@@ -969,7 +954,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
 
        set_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags);
        wake_up(&itv->event_waitq);
-       v4l2_event_queue(s->vdev, &ev);
+       v4l2_event_queue(&s->vdev, &ev);
 
        /* wake up wait queues */
        wake_up(&s->waitq);
@@ -982,7 +967,7 @@ int ivtv_passthrough_mode(struct ivtv *itv, int enable)
        struct ivtv_stream *yuv_stream = &itv->streams[IVTV_ENC_STREAM_TYPE_YUV];
        struct ivtv_stream *dec_stream = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV];
 
-       if (yuv_stream->vdev == NULL || dec_stream->vdev == NULL)
+       if (yuv_stream->vdev.v4l2_dev == NULL || dec_stream->vdev.v4l2_dev == NULL)
                return -EINVAL;
 
        IVTV_DEBUG_INFO("ivtv ioctl: Select passthrough mode\n");
index a653a5136417df1bbf7eb4abdbb3789a3cd55bc8..3d76a415fbd8892a1b425873259177a1314d2d02 100644 (file)
@@ -23,7 +23,7 @@
 
 int ivtv_streams_setup(struct ivtv *itv);
 int ivtv_streams_register(struct ivtv *itv);
-void ivtv_streams_cleanup(struct ivtv *itv, int unregister);
+void ivtv_streams_cleanup(struct ivtv *itv);
 
 /* Capture related */
 int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s);