media: vivid: move the devnode creation logic to a separate function
authorMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Tue, 1 Sep 2020 13:43:45 +0000 (15:43 +0200)
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Mon, 7 Sep 2020 14:01:57 +0000 (16:01 +0200)
In order to reduce even further the size of the big
vivid_create_instance() function, let's place the part of the
logic which creates the device nodes into a separate function.

    With this and the past patches, those warnings finally
    vanishes:

            drivers/media/test-drivers/vivid/vivid-core.c: drivers/media/test-drivers/vivid/vivid-core.c:1189 vivid_create_instance() parse error: turning off implications after 60 seconds
            drivers/media/test-drivers/vivid/vivid-core.c: drivers/media/test-drivers/vivid/vivid-core.c:1257 vivid_create_instance() parse error: __split_smt: function too hairy.  Giving up after 303 seconds

The init code also seems more organized after breaking the long
function into a smaller set.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
drivers/media/test-drivers/vivid/vivid-core.c

index 69cc845..54df7e0 100644 (file)
@@ -1306,245 +1306,17 @@ static int vivid_create_queues(struct vivid_dev *dev)
        return 0;
 }
 
-static int vivid_create_instance(struct platform_device *pdev, int inst)
+static int vivid_create_devnodes(struct platform_device *pdev,
+                                struct vivid_dev *dev, int inst,
+                                unsigned int cec_tx_bus_cnt,
+                                v4l2_std_id tvnorms_cap,
+                                v4l2_std_id tvnorms_out,
+                                unsigned in_type_counter[4],
+                                unsigned out_type_counter[4])
 {
-       static const struct v4l2_dv_timings def_dv_timings =
-                                       V4L2_DV_BT_CEA_1280X720P60;
-       unsigned in_type_counter[4] = { 0, 0, 0, 0 };
-       unsigned out_type_counter[4] = { 0, 0, 0, 0 };
-       int ccs_cap = ccs_cap_mode[inst];
-       int ccs_out = ccs_out_mode[inst];
-       bool has_tuner;
-       bool has_modulator;
-       struct vivid_dev *dev;
        struct video_device *vfd;
-       unsigned node_type = node_types[inst];
-       v4l2_std_id tvnorms_cap = 0, tvnorms_out = 0;
-       int ret;
-       int i;
-#ifdef CONFIG_VIDEO_VIVID_CEC
-       unsigned int cec_tx_bus_cnt = 0;
-#endif
-
-       /* allocate main vivid state structure */
-       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-       if (!dev)
-               return -ENOMEM;
-
-       dev->inst = inst;
-
-#ifdef CONFIG_MEDIA_CONTROLLER
-       dev->v4l2_dev.mdev = &dev->mdev;
-
-       /* Initialize media device */
-       strscpy(dev->mdev.model, VIVID_MODULE_NAME, sizeof(dev->mdev.model));
-       snprintf(dev->mdev.bus_info, sizeof(dev->mdev.bus_info),
-                "platform:%s-%03d", VIVID_MODULE_NAME, inst);
-       dev->mdev.dev = &pdev->dev;
-       media_device_init(&dev->mdev);
-       dev->mdev.ops = &vivid_media_ops;
-#endif
-
-       /* register v4l2_device */
-       snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name),
-                       "%s-%03d", VIVID_MODULE_NAME, inst);
-       ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
-       if (ret) {
-               kfree(dev);
-               return ret;
-       }
-       dev->v4l2_dev.release = vivid_dev_release;
-
-       ret = vivid_detect_feature_set(dev, inst, node_type,
-                                      &has_tuner, &has_modulator,
-                                      &ccs_cap, &ccs_out,
-                                      in_type_counter, out_type_counter);
-       if (ret) {
-               kfree(dev);
-               return ret;
-       }
-
-       vivid_set_capabilities(dev);
-
-       ret = -ENOMEM;
-       /* initialize the test pattern generator */
-       tpg_init(&dev->tpg, 640, 360);
-       if (tpg_alloc(&dev->tpg, array_size(MAX_WIDTH, MAX_ZOOM)))
-               goto free_dev;
-       dev->scaled_line = vzalloc(array_size(MAX_WIDTH, MAX_ZOOM));
-       if (!dev->scaled_line)
-               goto free_dev;
-       dev->blended_line = vzalloc(array_size(MAX_WIDTH, MAX_ZOOM));
-       if (!dev->blended_line)
-               goto free_dev;
-
-       /* load the edid */
-       dev->edid = vmalloc(array_size(256, 128));
-       if (!dev->edid)
-               goto free_dev;
-
-       ret = vivid_init_dv_timings(dev);
-       if (ret < 0)
-               goto free_dev;
-
-       vivid_disable_unused_ioctls(dev, has_tuner, has_modulator,
-                                   in_type_counter, out_type_counter);
-
-       /* configure internal data */
-       dev->fmt_cap = &vivid_formats[0];
-       dev->fmt_out = &vivid_formats[0];
-       if (!dev->multiplanar)
-               vivid_formats[0].data_offset[0] = 0;
-       dev->webcam_size_idx = 1;
-       dev->webcam_ival_idx = 3;
-       tpg_s_fourcc(&dev->tpg, dev->fmt_cap->fourcc);
-       dev->std_out = V4L2_STD_PAL;
-       if (dev->input_type[0] == TV || dev->input_type[0] == SVID)
-               tvnorms_cap = V4L2_STD_ALL;
-       if (dev->output_type[0] == SVID)
-               tvnorms_out = V4L2_STD_ALL;
-       for (i = 0; i < MAX_INPUTS; i++) {
-               dev->dv_timings_cap[i] = def_dv_timings;
-               dev->std_cap[i] = V4L2_STD_PAL;
-       }
-       dev->dv_timings_out = def_dv_timings;
-       dev->tv_freq = 2804 /* 175.25 * 16 */;
-       dev->tv_audmode = V4L2_TUNER_MODE_STEREO;
-       dev->tv_field_cap = V4L2_FIELD_INTERLACED;
-       dev->tv_field_out = V4L2_FIELD_INTERLACED;
-       dev->radio_rx_freq = 95000 * 16;
-       dev->radio_rx_audmode = V4L2_TUNER_MODE_STEREO;
-       if (dev->has_radio_tx) {
-               dev->radio_tx_freq = 95500 * 16;
-               dev->radio_rds_loop = false;
-       }
-       dev->radio_tx_subchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_RDS;
-       dev->sdr_adc_freq = 300000;
-       dev->sdr_fm_freq = 50000000;
-       dev->sdr_pixelformat = V4L2_SDR_FMT_CU8;
-       dev->sdr_buffersize = SDR_CAP_SAMPLES_PER_BUF * 2;
-
-       dev->edid_max_blocks = dev->edid_blocks = 2;
-       memcpy(dev->edid, vivid_hdmi_edid, sizeof(vivid_hdmi_edid));
-       dev->radio_rds_init_time = ktime_get();
-
-       /* create all controls */
-       ret = vivid_create_controls(dev, ccs_cap == -1, ccs_out == -1, no_error_inj,
-                       in_type_counter[TV] || in_type_counter[SVID] ||
-                       out_type_counter[SVID],
-                       in_type_counter[HDMI] || out_type_counter[HDMI]);
-       if (ret)
-               goto unreg_dev;
-
-       /* enable/disable interface specific controls */
-       if (dev->num_outputs && dev->output_type[0] != HDMI)
-               v4l2_ctrl_activate(dev->ctrl_display_present, false);
-       if (dev->num_inputs && dev->input_type[0] != HDMI) {
-               v4l2_ctrl_activate(dev->ctrl_dv_timings_signal_mode, false);
-               v4l2_ctrl_activate(dev->ctrl_dv_timings, false);
-       } else if (dev->num_inputs && dev->input_type[0] == HDMI) {
-               v4l2_ctrl_activate(dev->ctrl_std_signal_mode, false);
-               v4l2_ctrl_activate(dev->ctrl_standard, false);
-       }
-
-       /*
-        * update the capture and output formats to do a proper initial
-        * configuration.
-        */
-       vivid_update_format_cap(dev, false);
-       vivid_update_format_out(dev);
-
-       /* initialize overlay */
-       dev->fb_cap.fmt.width = dev->src_rect.width;
-       dev->fb_cap.fmt.height = dev->src_rect.height;
-       dev->fb_cap.fmt.pixelformat = dev->fmt_cap->fourcc;
-       dev->fb_cap.fmt.bytesperline = dev->src_rect.width * tpg_g_twopixelsize(&dev->tpg, 0) / 2;
-       dev->fb_cap.fmt.sizeimage = dev->src_rect.height * dev->fb_cap.fmt.bytesperline;
-
-       /* update touch configuration */
-       dev->timeperframe_tch_cap.numerator = 1;
-       dev->timeperframe_tch_cap.denominator = 10;
-       vivid_set_touch(dev, 0);
-
-       /* initialize locks */
-       spin_lock_init(&dev->slock);
-       mutex_init(&dev->mutex);
-
-       /* init dma queues */
-       INIT_LIST_HEAD(&dev->vid_cap_active);
-       INIT_LIST_HEAD(&dev->vid_out_active);
-       INIT_LIST_HEAD(&dev->vbi_cap_active);
-       INIT_LIST_HEAD(&dev->vbi_out_active);
-       INIT_LIST_HEAD(&dev->sdr_cap_active);
-       INIT_LIST_HEAD(&dev->meta_cap_active);
-       INIT_LIST_HEAD(&dev->meta_out_active);
-       INIT_LIST_HEAD(&dev->touch_cap_active);
-
-       INIT_LIST_HEAD(&dev->cec_work_list);
-       spin_lock_init(&dev->cec_slock);
-       /*
-        * Same as create_singlethread_workqueue, but now I can use the
-        * string formatting of alloc_ordered_workqueue.
-        */
-       dev->cec_workqueue = alloc_ordered_workqueue("vivid-%03d-cec",
-                                                    WQ_MEM_RECLAIM, inst);
-       if (!dev->cec_workqueue) {
-               ret = -ENOMEM;
-               goto unreg_dev;
-       }
-
-       if (allocators[inst] == 1)
-               dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
-
-       ret = vivid_create_queues(dev);
-       if (ret)
-               goto unreg_dev;
-
-#ifdef CONFIG_VIDEO_VIVID_CEC
-       if (dev->has_vid_cap && in_type_counter[HDMI]) {
-               struct cec_adapter *adap;
-
-               adap = vivid_cec_alloc_adap(dev, 0, false);
-               ret = PTR_ERR_OR_ZERO(adap);
-               if (ret < 0)
-                       goto unreg_dev;
-               dev->cec_rx_adap = adap;
-       }
-
-       if (dev->has_vid_out) {
-               for (i = 0; i < dev->num_outputs; i++) {
-                       struct cec_adapter *adap;
-
-                       if (dev->output_type[i] != HDMI)
-                               continue;
-
-                       dev->cec_output2bus_map[i] = cec_tx_bus_cnt;
-                       adap = vivid_cec_alloc_adap(dev, cec_tx_bus_cnt, true);
-                       ret = PTR_ERR_OR_ZERO(adap);
-                       if (ret < 0) {
-                               for (i = 0; i < dev->num_outputs; i++)
-                                       cec_delete_adapter(dev->cec_tx_adap[i]);
-                               goto unreg_dev;
-                       }
-
-                       dev->cec_tx_adap[cec_tx_bus_cnt] = adap;
-                       cec_tx_bus_cnt++;
-               }
-       }
-#endif
+       int ret, i;
 
-       v4l2_ctrl_handler_setup(&dev->ctrl_hdl_vid_cap);
-       v4l2_ctrl_handler_setup(&dev->ctrl_hdl_vid_out);
-       v4l2_ctrl_handler_setup(&dev->ctrl_hdl_vbi_cap);
-       v4l2_ctrl_handler_setup(&dev->ctrl_hdl_vbi_out);
-       v4l2_ctrl_handler_setup(&dev->ctrl_hdl_radio_rx);
-       v4l2_ctrl_handler_setup(&dev->ctrl_hdl_radio_tx);
-       v4l2_ctrl_handler_setup(&dev->ctrl_hdl_sdr_cap);
-       v4l2_ctrl_handler_setup(&dev->ctrl_hdl_meta_cap);
-       v4l2_ctrl_handler_setup(&dev->ctrl_hdl_meta_out);
-       v4l2_ctrl_handler_setup(&dev->ctrl_hdl_touch_cap);
-
-       /* finally start creating the device nodes */
        if (dev->has_vid_cap) {
                vfd = &dev->vid_cap_dev;
                snprintf(vfd->name, sizeof(vfd->name),
@@ -1568,7 +1340,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
                dev->vid_cap_pad.flags = MEDIA_PAD_FL_SINK;
                ret = media_entity_pads_init(&vfd->entity, 1, &dev->vid_cap_pad);
                if (ret)
-                       goto unreg_dev;
+                       return ret;
 #endif
 
 #ifdef CONFIG_VIDEO_VIVID_CEC
@@ -1577,7 +1349,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
                        if (ret < 0) {
                                cec_delete_adapter(dev->cec_rx_adap);
                                dev->cec_rx_adap = NULL;
-                               goto unreg_dev;
+                               return ret;
                        }
                        cec_s_phys_addr(dev->cec_rx_adap, 0, false);
                        v4l2_info(&dev->v4l2_dev, "CEC adapter %s registered for HDMI input 0\n",
@@ -1587,7 +1359,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
 
                ret = video_register_device(vfd, VFL_TYPE_VIDEO, vid_cap_nr[inst]);
                if (ret < 0)
-                       goto unreg_dev;
+                       return ret;
                v4l2_info(&dev->v4l2_dev, "V4L2 capture device registered as %s\n",
                                          video_device_node_name(vfd));
        }
@@ -1616,7 +1388,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
                dev->vid_out_pad.flags = MEDIA_PAD_FL_SOURCE;
                ret = media_entity_pads_init(&vfd->entity, 1, &dev->vid_out_pad);
                if (ret)
-                       goto unreg_dev;
+                       return ret;
 #endif
 
 #ifdef CONFIG_VIDEO_VIVID_CEC
@@ -1627,7 +1399,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
                                        cec_delete_adapter(dev->cec_tx_adap[i]);
                                        dev->cec_tx_adap[i] = NULL;
                                }
-                               goto unreg_dev;
+                               return ret;
                        }
                        v4l2_info(&dev->v4l2_dev, "CEC adapter %s registered for HDMI output %d\n",
                                  dev_name(&dev->cec_tx_adap[i]->devnode.dev), i);
@@ -1640,7 +1412,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
 
                ret = video_register_device(vfd, VFL_TYPE_VIDEO, vid_out_nr[inst]);
                if (ret < 0)
-                       goto unreg_dev;
+                       return ret;
                v4l2_info(&dev->v4l2_dev, "V4L2 output device registered as %s\n",
                                          video_device_node_name(vfd));
        }
@@ -1663,12 +1435,12 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
                dev->vbi_cap_pad.flags = MEDIA_PAD_FL_SINK;
                ret = media_entity_pads_init(&vfd->entity, 1, &dev->vbi_cap_pad);
                if (ret)
-                       goto unreg_dev;
+                       return ret;
 #endif
 
                ret = video_register_device(vfd, VFL_TYPE_VBI, vbi_cap_nr[inst]);
                if (ret < 0)
-                       goto unreg_dev;
+                       return ret;
                v4l2_info(&dev->v4l2_dev, "V4L2 capture device registered as %s, supports %s VBI\n",
                                          video_device_node_name(vfd),
                                          (dev->has_raw_vbi_cap && dev->has_sliced_vbi_cap) ?
@@ -1695,12 +1467,12 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
                dev->vbi_out_pad.flags = MEDIA_PAD_FL_SOURCE;
                ret = media_entity_pads_init(&vfd->entity, 1, &dev->vbi_out_pad);
                if (ret)
-                       goto unreg_dev;
+                       return ret;
 #endif
 
                ret = video_register_device(vfd, VFL_TYPE_VBI, vbi_out_nr[inst]);
                if (ret < 0)
-                       goto unreg_dev;
+                       return ret;
                v4l2_info(&dev->v4l2_dev, "V4L2 output device registered as %s, supports %s VBI\n",
                                          video_device_node_name(vfd),
                                          (dev->has_raw_vbi_out && dev->has_sliced_vbi_out) ?
@@ -1725,12 +1497,12 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
                dev->sdr_cap_pad.flags = MEDIA_PAD_FL_SINK;
                ret = media_entity_pads_init(&vfd->entity, 1, &dev->sdr_cap_pad);
                if (ret)
-                       goto unreg_dev;
+                       return ret;
 #endif
 
                ret = video_register_device(vfd, VFL_TYPE_SDR, sdr_cap_nr[inst]);
                if (ret < 0)
-                       goto unreg_dev;
+                       return ret;
                v4l2_info(&dev->v4l2_dev, "V4L2 capture device registered as %s\n",
                                          video_device_node_name(vfd));
        }
@@ -1749,7 +1521,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
 
                ret = video_register_device(vfd, VFL_TYPE_RADIO, radio_rx_nr[inst]);
                if (ret < 0)
-                       goto unreg_dev;
+                       return ret;
                v4l2_info(&dev->v4l2_dev, "V4L2 receiver device registered as %s\n",
                                          video_device_node_name(vfd));
        }
@@ -1769,7 +1541,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
 
                ret = video_register_device(vfd, VFL_TYPE_RADIO, radio_tx_nr[inst]);
                if (ret < 0)
-                       goto unreg_dev;
+                       return ret;
                v4l2_info(&dev->v4l2_dev, "V4L2 transmitter device registered as %s\n",
                                          video_device_node_name(vfd));
        }
@@ -1792,12 +1564,12 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
                ret = media_entity_pads_init(&vfd->entity, 1,
                                             &dev->meta_cap_pad);
                if (ret)
-                       goto unreg_dev;
+                       return ret;
 #endif
                ret = video_register_device(vfd, VFL_TYPE_VIDEO,
                                            meta_cap_nr[inst]);
                if (ret < 0)
-                       goto unreg_dev;
+                       return ret;
                v4l2_info(&dev->v4l2_dev,
                          "V4L2 metadata capture device registered as %s\n",
                          video_device_node_name(vfd));
@@ -1822,12 +1594,12 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
                ret = media_entity_pads_init(&vfd->entity, 1,
                                             &dev->meta_out_pad);
                if (ret)
-                       goto unreg_dev;
+                       return ret;
 #endif
                ret = video_register_device(vfd, VFL_TYPE_VIDEO,
                                            meta_out_nr[inst]);
                if (ret < 0)
-                       goto unreg_dev;
+                       return ret;
                v4l2_info(&dev->v4l2_dev,
                          "V4L2 metadata output device registered as %s\n",
                          video_device_node_name(vfd));
@@ -1851,12 +1623,12 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
                ret = media_entity_pads_init(&vfd->entity, 1,
                                             &dev->touch_cap_pad);
                if (ret)
-                       goto unreg_dev;
+                       return ret;
 #endif
                ret = video_register_device(vfd, VFL_TYPE_TOUCH,
                                            touch_cap_nr[inst]);
                if (ret < 0)
-                       goto unreg_dev;
+                       return ret;
                v4l2_info(&dev->v4l2_dev,
                          "V4L2 touch capture device registered as %s\n",
                          video_device_node_name(vfd));
@@ -1868,10 +1640,256 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
        if (ret) {
                dev_err(dev->mdev.dev,
                        "media device register failed (err=%d)\n", ret);
+               return ret;
+       }
+#endif
+       return 0;
+}
+
+static int vivid_create_instance(struct platform_device *pdev, int inst)
+{
+       static const struct v4l2_dv_timings def_dv_timings =
+                                       V4L2_DV_BT_CEA_1280X720P60;
+       unsigned in_type_counter[4] = { 0, 0, 0, 0 };
+       unsigned out_type_counter[4] = { 0, 0, 0, 0 };
+       int ccs_cap = ccs_cap_mode[inst];
+       int ccs_out = ccs_out_mode[inst];
+       bool has_tuner;
+       bool has_modulator;
+       struct vivid_dev *dev;
+       unsigned node_type = node_types[inst];
+       v4l2_std_id tvnorms_cap = 0, tvnorms_out = 0;
+       int ret;
+       int i;
+#ifdef CONFIG_VIDEO_VIVID_CEC
+       unsigned int cec_tx_bus_cnt = 0;
+#endif
+
+       /* allocate main vivid state structure */
+       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+       if (!dev)
+               return -ENOMEM;
+
+       dev->inst = inst;
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+       dev->v4l2_dev.mdev = &dev->mdev;
+
+       /* Initialize media device */
+       strscpy(dev->mdev.model, VIVID_MODULE_NAME, sizeof(dev->mdev.model));
+       snprintf(dev->mdev.bus_info, sizeof(dev->mdev.bus_info),
+                "platform:%s-%03d", VIVID_MODULE_NAME, inst);
+       dev->mdev.dev = &pdev->dev;
+       media_device_init(&dev->mdev);
+       dev->mdev.ops = &vivid_media_ops;
+#endif
+
+       /* register v4l2_device */
+       snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name),
+                       "%s-%03d", VIVID_MODULE_NAME, inst);
+       ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
+       if (ret) {
+               kfree(dev);
+               return ret;
+       }
+       dev->v4l2_dev.release = vivid_dev_release;
+
+       ret = vivid_detect_feature_set(dev, inst, node_type,
+                                      &has_tuner, &has_modulator,
+                                      &ccs_cap, &ccs_out,
+                                      in_type_counter, out_type_counter);
+       if (ret) {
+               kfree(dev);
+               return ret;
+       }
+
+       vivid_set_capabilities(dev);
+
+       ret = -ENOMEM;
+       /* initialize the test pattern generator */
+       tpg_init(&dev->tpg, 640, 360);
+       if (tpg_alloc(&dev->tpg, array_size(MAX_WIDTH, MAX_ZOOM)))
+               goto free_dev;
+       dev->scaled_line = vzalloc(array_size(MAX_WIDTH, MAX_ZOOM));
+       if (!dev->scaled_line)
+               goto free_dev;
+       dev->blended_line = vzalloc(array_size(MAX_WIDTH, MAX_ZOOM));
+       if (!dev->blended_line)
+               goto free_dev;
+
+       /* load the edid */
+       dev->edid = vmalloc(array_size(256, 128));
+       if (!dev->edid)
+               goto free_dev;
+
+       ret = vivid_init_dv_timings(dev);
+       if (ret < 0)
+               goto free_dev;
+
+       vivid_disable_unused_ioctls(dev, has_tuner, has_modulator,
+                                   in_type_counter, out_type_counter);
+
+       /* configure internal data */
+       dev->fmt_cap = &vivid_formats[0];
+       dev->fmt_out = &vivid_formats[0];
+       if (!dev->multiplanar)
+               vivid_formats[0].data_offset[0] = 0;
+       dev->webcam_size_idx = 1;
+       dev->webcam_ival_idx = 3;
+       tpg_s_fourcc(&dev->tpg, dev->fmt_cap->fourcc);
+       dev->std_out = V4L2_STD_PAL;
+       if (dev->input_type[0] == TV || dev->input_type[0] == SVID)
+               tvnorms_cap = V4L2_STD_ALL;
+       if (dev->output_type[0] == SVID)
+               tvnorms_out = V4L2_STD_ALL;
+       for (i = 0; i < MAX_INPUTS; i++) {
+               dev->dv_timings_cap[i] = def_dv_timings;
+               dev->std_cap[i] = V4L2_STD_PAL;
+       }
+       dev->dv_timings_out = def_dv_timings;
+       dev->tv_freq = 2804 /* 175.25 * 16 */;
+       dev->tv_audmode = V4L2_TUNER_MODE_STEREO;
+       dev->tv_field_cap = V4L2_FIELD_INTERLACED;
+       dev->tv_field_out = V4L2_FIELD_INTERLACED;
+       dev->radio_rx_freq = 95000 * 16;
+       dev->radio_rx_audmode = V4L2_TUNER_MODE_STEREO;
+       if (dev->has_radio_tx) {
+               dev->radio_tx_freq = 95500 * 16;
+               dev->radio_rds_loop = false;
+       }
+       dev->radio_tx_subchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_RDS;
+       dev->sdr_adc_freq = 300000;
+       dev->sdr_fm_freq = 50000000;
+       dev->sdr_pixelformat = V4L2_SDR_FMT_CU8;
+       dev->sdr_buffersize = SDR_CAP_SAMPLES_PER_BUF * 2;
+
+       dev->edid_max_blocks = dev->edid_blocks = 2;
+       memcpy(dev->edid, vivid_hdmi_edid, sizeof(vivid_hdmi_edid));
+       dev->radio_rds_init_time = ktime_get();
+
+       /* create all controls */
+       ret = vivid_create_controls(dev, ccs_cap == -1, ccs_out == -1, no_error_inj,
+                       in_type_counter[TV] || in_type_counter[SVID] ||
+                       out_type_counter[SVID],
+                       in_type_counter[HDMI] || out_type_counter[HDMI]);
+       if (ret)
                goto unreg_dev;
+
+       /* enable/disable interface specific controls */
+       if (dev->num_outputs && dev->output_type[0] != HDMI)
+               v4l2_ctrl_activate(dev->ctrl_display_present, false);
+       if (dev->num_inputs && dev->input_type[0] != HDMI) {
+               v4l2_ctrl_activate(dev->ctrl_dv_timings_signal_mode, false);
+               v4l2_ctrl_activate(dev->ctrl_dv_timings, false);
+       } else if (dev->num_inputs && dev->input_type[0] == HDMI) {
+               v4l2_ctrl_activate(dev->ctrl_std_signal_mode, false);
+               v4l2_ctrl_activate(dev->ctrl_standard, false);
+       }
+
+       /*
+        * update the capture and output formats to do a proper initial
+        * configuration.
+        */
+       vivid_update_format_cap(dev, false);
+       vivid_update_format_out(dev);
+
+       /* initialize overlay */
+       dev->fb_cap.fmt.width = dev->src_rect.width;
+       dev->fb_cap.fmt.height = dev->src_rect.height;
+       dev->fb_cap.fmt.pixelformat = dev->fmt_cap->fourcc;
+       dev->fb_cap.fmt.bytesperline = dev->src_rect.width * tpg_g_twopixelsize(&dev->tpg, 0) / 2;
+       dev->fb_cap.fmt.sizeimage = dev->src_rect.height * dev->fb_cap.fmt.bytesperline;
+
+       /* update touch configuration */
+       dev->timeperframe_tch_cap.numerator = 1;
+       dev->timeperframe_tch_cap.denominator = 10;
+       vivid_set_touch(dev, 0);
+
+       /* initialize locks */
+       spin_lock_init(&dev->slock);
+       mutex_init(&dev->mutex);
+
+       /* init dma queues */
+       INIT_LIST_HEAD(&dev->vid_cap_active);
+       INIT_LIST_HEAD(&dev->vid_out_active);
+       INIT_LIST_HEAD(&dev->vbi_cap_active);
+       INIT_LIST_HEAD(&dev->vbi_out_active);
+       INIT_LIST_HEAD(&dev->sdr_cap_active);
+       INIT_LIST_HEAD(&dev->meta_cap_active);
+       INIT_LIST_HEAD(&dev->meta_out_active);
+       INIT_LIST_HEAD(&dev->touch_cap_active);
+
+       INIT_LIST_HEAD(&dev->cec_work_list);
+       spin_lock_init(&dev->cec_slock);
+       /*
+        * Same as create_singlethread_workqueue, but now I can use the
+        * string formatting of alloc_ordered_workqueue.
+        */
+       dev->cec_workqueue = alloc_ordered_workqueue("vivid-%03d-cec",
+                                                    WQ_MEM_RECLAIM, inst);
+       if (!dev->cec_workqueue) {
+               ret = -ENOMEM;
+               goto unreg_dev;
+       }
+
+       if (allocators[inst] == 1)
+               dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+
+       ret = vivid_create_queues(dev);
+       if (ret)
+               goto unreg_dev;
+
+#ifdef CONFIG_VIDEO_VIVID_CEC
+       if (dev->has_vid_cap && in_type_counter[HDMI]) {
+               struct cec_adapter *adap;
+
+               adap = vivid_cec_alloc_adap(dev, 0, false);
+               ret = PTR_ERR_OR_ZERO(adap);
+               if (ret < 0)
+                       goto unreg_dev;
+               dev->cec_rx_adap = adap;
+       }
+
+       if (dev->has_vid_out) {
+               for (i = 0; i < dev->num_outputs; i++) {
+                       struct cec_adapter *adap;
+
+                       if (dev->output_type[i] != HDMI)
+                               continue;
+
+                       dev->cec_output2bus_map[i] = cec_tx_bus_cnt;
+                       adap = vivid_cec_alloc_adap(dev, cec_tx_bus_cnt, true);
+                       ret = PTR_ERR_OR_ZERO(adap);
+                       if (ret < 0) {
+                               for (i = 0; i < dev->num_outputs; i++)
+                                       cec_delete_adapter(dev->cec_tx_adap[i]);
+                               goto unreg_dev;
+                       }
+
+                       dev->cec_tx_adap[cec_tx_bus_cnt] = adap;
+                       cec_tx_bus_cnt++;
+               }
        }
 #endif
 
+       v4l2_ctrl_handler_setup(&dev->ctrl_hdl_vid_cap);
+       v4l2_ctrl_handler_setup(&dev->ctrl_hdl_vid_out);
+       v4l2_ctrl_handler_setup(&dev->ctrl_hdl_vbi_cap);
+       v4l2_ctrl_handler_setup(&dev->ctrl_hdl_vbi_out);
+       v4l2_ctrl_handler_setup(&dev->ctrl_hdl_radio_rx);
+       v4l2_ctrl_handler_setup(&dev->ctrl_hdl_radio_tx);
+       v4l2_ctrl_handler_setup(&dev->ctrl_hdl_sdr_cap);
+       v4l2_ctrl_handler_setup(&dev->ctrl_hdl_meta_cap);
+       v4l2_ctrl_handler_setup(&dev->ctrl_hdl_meta_out);
+       v4l2_ctrl_handler_setup(&dev->ctrl_hdl_touch_cap);
+
+       /* finally start creating the device nodes */
+       ret = vivid_create_devnodes(pdev, dev, inst, cec_tx_bus_cnt,
+                                   tvnorms_cap, tvnorms_out,
+                                   in_type_counter, out_type_counter);
+       if (ret)
+               goto unreg_dev;
+
        /* Now that everything is fine, let's add it to device list */
        vivid_devs[inst] = dev;