media: staging: media: zoran: move videodev alloc
authorCorentin Labbe <clabbe@baylibre.com>
Tue, 14 Dec 2021 16:16:26 +0000 (17:16 +0100)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Sun, 23 Jan 2022 20:18:39 +0000 (21:18 +0100)
Move some code out of zr36057_init() and create new functions for handling
zr->video_dev. This permit to ease code reading and fix a zr->video_dev
memory leak.

Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
drivers/staging/media/zoran/zoran.h
drivers/staging/media/zoran/zoran_card.c
drivers/staging/media/zoran/zoran_driver.c

index 981cb63..c36b33f 100644 (file)
@@ -315,6 +315,6 @@ static inline struct zoran *to_zoran(struct v4l2_device *v4l2_dev)
 
 #endif
 
-int zoran_queue_init(struct zoran *zr, struct vb2_queue *vq);
+int zoran_queue_init(struct zoran *zr, struct vb2_queue *vq, int dir);
 void zoran_queue_exit(struct zoran *zr);
 int zr_set_buf(struct zoran *zr);
index ffbb4ac..29120f2 100644 (file)
@@ -885,6 +885,52 @@ int zoran_check_jpg_settings(struct zoran *zr,
        return 0;
 }
 
+static int zoran_init_video_device(struct zoran *zr, struct video_device *video_dev, int dir)
+{
+       int err;
+
+       /* Now add the template and register the device unit. */
+       *video_dev = zoran_template;
+       video_dev->v4l2_dev = &zr->v4l2_dev;
+       video_dev->lock = &zr->lock;
+       video_dev->device_caps = V4L2_CAP_STREAMING | dir;
+
+       strscpy(video_dev->name, ZR_DEVNAME(zr), sizeof(video_dev->name));
+       /*
+        * It's not a mem2mem device, but you can both capture and output from one and the same
+        * device. This should really be split up into two device nodes, but that's a job for
+        * another day.
+        */
+       video_dev->vfl_dir = VFL_DIR_M2M;
+       zoran_queue_init(zr, &zr->vq, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+
+       err = video_register_device(video_dev, VFL_TYPE_VIDEO, video_nr[zr->id]);
+       if (err < 0)
+               return err;
+       video_set_drvdata(video_dev, zr);
+       return 0;
+}
+
+static void zoran_exit_video_devices(struct zoran *zr)
+{
+       video_unregister_device(zr->video_dev);
+       kfree(zr->video_dev);
+}
+
+static int zoran_init_video_devices(struct zoran *zr)
+{
+       int err;
+
+       zr->video_dev = video_device_alloc();
+       if (!zr->video_dev)
+               return -ENOMEM;
+
+       err = zoran_init_video_device(zr, zr->video_dev, V4L2_CAP_VIDEO_CAPTURE);
+       if (err)
+               kfree(zr->video_dev);
+       return err;
+}
+
 void zoran_open_init_params(struct zoran *zr)
 {
        int i;
@@ -956,17 +1002,11 @@ static int zr36057_init(struct zoran *zr)
        zoran_open_init_params(zr);
 
        /* allocate memory *before* doing anything to the hardware in case allocation fails */
-       zr->video_dev = video_device_alloc();
-       if (!zr->video_dev) {
-               err = -ENOMEM;
-               goto exit;
-       }
        zr->stat_com = dma_alloc_coherent(&zr->pci_dev->dev,
                                          BUZ_NUM_STAT_COM * sizeof(u32),
                                          &zr->p_sc, GFP_KERNEL);
        if (!zr->stat_com) {
-               err = -ENOMEM;
-               goto exit_video;
+               return -ENOMEM;
        }
        for (j = 0; j < BUZ_NUM_STAT_COM; j++)
                zr->stat_com[j] = cpu_to_le32(1); /* mark as unavailable to zr36057 */
@@ -979,26 +1019,9 @@ static int zr36057_init(struct zoran *zr)
                goto exit_statcom;
        }
 
-       /* Now add the template and register the device unit. */
-       *zr->video_dev = zoran_template;
-       zr->video_dev->v4l2_dev = &zr->v4l2_dev;
-       zr->video_dev->lock = &zr->lock;
-       zr->video_dev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE;
-
-       strscpy(zr->video_dev->name, ZR_DEVNAME(zr), sizeof(zr->video_dev->name));
-       /*
-        * It's not a mem2mem device, but you can both capture and output from one and the same
-        * device. This should really be split up into two device nodes, but that's a job for
-        * another day.
-        */
-       zr->video_dev->vfl_dir = VFL_DIR_M2M;
-
-       zoran_queue_init(zr, &zr->vq);
-
-       err = video_register_device(zr->video_dev, VFL_TYPE_VIDEO, video_nr[zr->id]);
-       if (err < 0)
+       err = zoran_init_video_devices(zr);
+       if (err)
                goto exit_statcomb;
-       video_set_drvdata(zr->video_dev, zr);
 
        zoran_init_hardware(zr);
        if (!pass_through) {
@@ -1013,9 +1036,6 @@ exit_statcomb:
        dma_free_coherent(&zr->pci_dev->dev, BUZ_NUM_STAT_COM * sizeof(u32) * 2, zr->stat_comb, zr->p_scb);
 exit_statcom:
        dma_free_coherent(&zr->pci_dev->dev, BUZ_NUM_STAT_COM * sizeof(u32), zr->stat_com, zr->p_sc);
-exit_video:
-       kfree(zr->video_dev);
-exit:
        return err;
 }
 
@@ -1050,7 +1070,7 @@ static void zoran_remove(struct pci_dev *pdev)
        dma_free_coherent(&zr->pci_dev->dev, BUZ_NUM_STAT_COM * sizeof(u32) * 2, zr->stat_comb, zr->p_scb);
        pci_release_regions(pdev);
        pci_disable_device(zr->pci_dev);
-       video_unregister_device(zr->video_dev);
+       zoran_exit_video_devices(zr);
 exit_free:
        v4l2_ctrl_handler_free(&zr->hdl);
        v4l2_device_unregister(&zr->v4l2_dev);
index 46382e4..551db33 100644 (file)
@@ -1008,7 +1008,7 @@ static const struct vb2_ops zr_video_qops = {
        .wait_finish            = vb2_ops_wait_finish,
 };
 
-int zoran_queue_init(struct zoran *zr, struct vb2_queue *vq)
+int zoran_queue_init(struct zoran *zr, struct vb2_queue *vq, int dir)
 {
        int err;
 
@@ -1016,7 +1016,8 @@ int zoran_queue_init(struct zoran *zr, struct vb2_queue *vq)
        INIT_LIST_HEAD(&zr->queued_bufs);
 
        vq->dev = &zr->pci_dev->dev;
-       vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       vq->type = dir;
+
        vq->io_modes = VB2_USERPTR | VB2_DMABUF | VB2_MMAP | VB2_READ | VB2_WRITE;
        vq->drv_priv = zr;
        vq->buf_struct_size = sizeof(struct zr_buffer);