enable_irq(csid->irq);
 
-               ret = csid->ops->reset(csid);
+               ret = csid->res->hw_ops->reset(csid);
                if (ret < 0) {
                        disable_irq(csid->irq);
                        camss_disable_clocks(csid->nclocks, csid->clock);
                        return ret;
                }
 
-               csid->ops->hw_version(csid);
+               csid->res->hw_ops->hw_version(csid);
        } else {
                disable_irq(csid->irq);
                camss_disable_clocks(csid->nclocks, csid->clock);
        }
 
        if (csid->phy.need_vc_update) {
-               csid->ops->configure_stream(csid, enable);
+               csid->res->hw_ops->configure_stream(csid, enable);
                csid->phy.need_vc_update = false;
        }
 
 
                        *fmt = *__csid_get_format(csid, sd_state,
                                                      MSM_CSID_PAD_SINK, which);
-                       fmt->code = csid->ops->src_pad_code(csid, fmt->code, 0, code);
+                       fmt->code = csid->res->hw_ops->src_pad_code(csid, fmt->code, 0, code);
                } else {
                        /* Test generator is enabled, set format on source */
                        /* pad to allow test generator usage */
                                                     MSM_CSID_PAD_SINK,
                                                     code->which);
 
-                       code->code = csid->ops->src_pad_code(csid, sink_fmt->code,
-                                                      code->index, 0);
+                       code->code = csid->res->hw_ops->src_pad_code(csid, sink_fmt->code,
+                                                                    code->index, 0);
                        if (!code->code)
                                return -EINVAL;
                } else {
 
        tg->enabled = !!value;
 
-       return csid->ops->configure_testgen_pattern(csid, value);
+       return csid->res->hw_ops->configure_testgen_pattern(csid, value);
 }
 
 /*
 
        csid->camss = camss;
        csid->id = id;
-       csid->ops = res->ops;
+       csid->res = &res->csid;
 
-       csid->ops->subdev_init(csid);
+       csid->res->hw_ops->subdev_init(csid);
 
        /* Memory */
 
        csid->irq = ret;
        snprintf(csid->irq_name, sizeof(csid->irq_name), "%s_%s%d",
                 dev_name(dev), MSM_CSID_NAME, csid->id);
-       ret = devm_request_irq(dev, csid->irq, csid->ops->isr,
+       ret = devm_request_irq(dev, csid->irq, csid->res->hw_ops->isr,
                               IRQF_TRIGGER_RISING | IRQF_NO_AUTOEN,
                               csid->irq_name, csid);
        if (ret < 0) {
 
 inline bool csid_is_lite(struct csid_device *csid)
 {
-       return csid->camss->res->csid_res[csid->id].is_lite;
+       return csid->camss->res->csid_res[csid->id].csid.is_lite;
 }
 
        void (*subdev_init)(struct csid_device *csid);
 };
 
+struct csid_subdev_resources {
+       bool is_lite;
+       const struct csid_hw_ops *hw_ops;
+};
+
 struct csid_device {
        struct camss *camss;
        u8 id;
        struct v4l2_ctrl *testgen_mode;
        const struct csid_format *formats;
        unsigned int nformats;
-       const struct csid_hw_ops *ops;
+       const struct csid_subdev_resources *res;
 };
 
 struct camss_subdev_resources;
 
 
                enable_irq(csiphy->irq);
 
-               csiphy->ops->reset(csiphy);
+               csiphy->res->hw_ops->reset(csiphy);
 
-               csiphy->ops->hw_version_read(csiphy, dev);
+               csiphy->res->hw_ops->hw_version_read(csiphy, dev);
        } else {
                disable_irq(csiphy->irq);
 
 {
        struct csiphy_config *cfg = &csiphy->cfg;
        s64 link_freq;
-       u8 lane_mask = csiphy->ops->get_lane_mask(&cfg->csi2->lane_cfg);
+       u8 lane_mask = csiphy->res->hw_ops->get_lane_mask(&cfg->csi2->lane_cfg);
        u8 bpp = csiphy_get_bpp(csiphy->formats, csiphy->nformats,
                                csiphy->fmt[MSM_CSIPHY_PAD_SINK].code);
        u8 num_lanes = csiphy->cfg.csi2->lane_cfg.num_data;
                wmb();
        }
 
-       csiphy->ops->lanes_enable(csiphy, cfg, link_freq, lane_mask);
+       csiphy->res->hw_ops->lanes_enable(csiphy, cfg, link_freq, lane_mask);
 
        return 0;
 }
  */
 static void csiphy_stream_off(struct csiphy_device *csiphy)
 {
-       csiphy->ops->lanes_disable(csiphy, &csiphy->cfg);
+       csiphy->res->hw_ops->lanes_disable(csiphy, &csiphy->cfg);
 }
 
 
        csiphy->camss = camss;
        csiphy->id = id;
        csiphy->cfg.combo_mode = 0;
-       csiphy->ops = res->ops;
+       csiphy->res = &res->csiphy;
 
        switch (camss->res->version) {
        case CAMSS_8x16:
        snprintf(csiphy->irq_name, sizeof(csiphy->irq_name), "%s_%s%d",
                 dev_name(dev), MSM_CSIPHY_NAME, csiphy->id);
 
-       ret = devm_request_irq(dev, csiphy->irq, csiphy->ops->isr,
+       ret = devm_request_irq(dev, csiphy->irq, csiphy->res->hw_ops->isr,
                               IRQF_TRIGGER_RISING | IRQF_NO_AUTOEN,
                               csiphy->irq_name, csiphy);
        if (ret < 0) {
 
        irqreturn_t (*isr)(int irq, void *dev);
 };
 
+struct csiphy_subdev_resources {
+       const struct csiphy_hw_ops *hw_ops;
+};
+
 struct csiphy_device {
        struct camss *camss;
        u8 id;
        u32 timer_clk_rate;
        struct csiphy_config cfg;
        struct v4l2_mbus_framefmt fmt[MSM_CSIPHY_PADS_NUM];
-       const struct csiphy_hw_ops *ops;
+       const struct csiphy_subdev_resources *res;
        const struct csiphy_format *formats;
        unsigned int nformats;
 };
 
        writel_relaxed(status0, vfe->base + VFE_IRQ_CLEAR_0);
        writel_relaxed(status1, vfe->base + VFE_IRQ_CLEAR_1);
 
-       for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) {
+       for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++) {
                vfe_bus_status[i] = readl_relaxed(vfe->base + VFE_BUS_IRQ_STATUS(i));
                writel_relaxed(vfe_bus_status[i], vfe->base + VFE_BUS_IRQ_CLEAR(i));
        }
        if (status0 & STATUS_0_RESET_ACK)
                vfe->isr_ops.reset_ack(vfe);
 
-       for (i = VFE_LINE_RDI0; i < vfe->line_num; i++)
+       for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++)
                if (status0 & STATUS_0_RDI_REG_UPDATE(i))
                        vfe->isr_ops.reg_update(vfe, i);
 
-       for (i = VFE_LINE_RDI0; i < vfe->line_num; i++)
+       for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++)
                if (status0 & STATUS_1_RDI_SOF(i))
                        vfe->isr_ops.sof(vfe, i);
 
 {
        struct vfe_device *vfe = to_vfe(line);
        struct vfe_output *output = &line->output;
-       const struct vfe_hw_ops *ops = vfe->ops;
+       const struct vfe_hw_ops *ops = vfe->res->hw_ops;
        struct media_entity *sensor;
        unsigned long flags;
        unsigned int frame_skip = 0;
        unsigned long flags;
 
        spin_lock_irqsave(&vfe->output_lock, flags);
-       vfe->ops->reg_update_clear(vfe, line_id);
+       vfe->res->hw_ops->reg_update_clear(vfe, line_id);
 
        output = &vfe->line[line_id].output;
 
 
        u32 value0, value1;
        int i, j;
 
-       vfe->ops->isr_read(vfe, &value0, &value1);
+       vfe->res->hw_ops->isr_read(vfe, &value0, &value1);
 
        dev_dbg(vfe->camss->dev, "VFE: status0 = 0x%08x, status1 = 0x%08x\n",
                value0, value1);
                vfe->isr_ops.reset_ack(vfe);
 
        if (value1 & VFE_0_IRQ_STATUS_1_VIOLATION)
-               vfe->ops->violation_read(vfe);
+               vfe->res->hw_ops->violation_read(vfe);
 
        if (value1 & VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK)
                vfe->isr_ops.halt_ack(vfe);
 
        u32 value0, value1;
        int i, j;
 
-       vfe->ops->isr_read(vfe, &value0, &value1);
+       vfe->res->hw_ops->isr_read(vfe, &value0, &value1);
 
        dev_dbg(vfe->camss->dev, "VFE: status0 = 0x%08x, status1 = 0x%08x\n",
                value0, value1);
                vfe->isr_ops.reset_ack(vfe);
 
        if (value1 & VFE_0_IRQ_STATUS_1_VIOLATION)
-               vfe->ops->violation_read(vfe);
+               vfe->res->hw_ops->violation_read(vfe);
 
        if (value1 & VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK)
                vfe->isr_ops.halt_ack(vfe);
 
-       for (i = VFE_LINE_RDI0; i < vfe->line_num; i++)
+       for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++)
                if (value0 & VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(i))
                        vfe->isr_ops.reg_update(vfe, i);
 
 
        u32 value0, value1;
        int i, j;
 
-       vfe->ops->isr_read(vfe, &value0, &value1);
+       vfe->res->hw_ops->isr_read(vfe, &value0, &value1);
 
        dev_dbg(vfe->camss->dev, "VFE: status0 = 0x%08x, status1 = 0x%08x\n",
                value0, value1);
                vfe->isr_ops.reset_ack(vfe);
 
        if (value1 & VFE_0_IRQ_STATUS_1_VIOLATION)
-               vfe->ops->violation_read(vfe);
+               vfe->res->hw_ops->violation_read(vfe);
 
        if (value1 & VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK)
                vfe->isr_ops.halt_ack(vfe);
 
-       for (i = VFE_LINE_RDI0; i < vfe->line_num; i++)
+       for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++)
                if (value0 & VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(i))
                        vfe->isr_ops.reg_update(vfe, i);
 
 
 {
        struct vfe_device *vfe = to_vfe(line);
        struct vfe_output *output = &line->output;
-       const struct vfe_hw_ops *ops = vfe->ops;
+       const struct vfe_hw_ops *ops = vfe->res->hw_ops;
        unsigned long flags;
        unsigned long time;
        unsigned int i;
                vfe->ops_gen1->wm_set_framedrop_pattern(vfe, output->wm_idx[i], drop_pattern);
        }
 
-       vfe->ops->reg_update(vfe, container_of(output, struct vfe_line, output)->id);
+       vfe->res->hw_ops->reg_update(vfe, container_of(output, struct vfe_line, output)->id);
 }
 
 static int vfe_enable_output(struct vfe_line *line)
 {
        struct vfe_device *vfe = to_vfe(line);
        struct vfe_output *output = &line->output;
-       const struct vfe_hw_ops *ops = vfe->ops;
+       const struct vfe_hw_ops *ops = vfe->res->hw_ops;
        struct media_entity *sensor;
        unsigned long flags;
        unsigned int frame_skip = 0;
        unsigned long flags;
 
        spin_lock_irqsave(&vfe->output_lock, flags);
-       vfe->ops->reg_update_clear(vfe, line_id);
+       vfe->res->hw_ops->reg_update_clear(vfe, line_id);
 
        output = &line->output;
 
 
 
        reinit_completion(&vfe->reset_complete);
 
-       vfe->ops->global_reset(vfe);
+       vfe->res->hw_ops->global_reset(vfe);
 
        time = wait_for_completion_timeout(&vfe->reset_complete,
                msecs_to_jiffies(VFE_RESET_TIMEOUT_MS));
 {
        int i;
 
-       for (i = 0; i < vfe->line_num; i++) {
+       for (i = 0; i < vfe->res->line_num; i++) {
                struct vfe_output *output = &vfe->line[i].output;
 
                output->state = VFE_OUTPUT_OFF;
 
        spin_lock_irqsave(&vfe->output_lock, flags);
        for (i = 0; i < output->wm_num; i++)
-               vfe->ops->vfe_wm_stop(vfe, output->wm_idx[i]);
+               vfe->res->hw_ops->vfe_wm_stop(vfe, output->wm_idx[i]);
        output->gen2.active_num = 0;
        spin_unlock_irqrestore(&vfe->output_lock, flags);
 
        int i, j;
        int ret;
 
-       for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) {
+       for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++) {
                ret = camss_get_pixel_clock(&vfe->line[i].subdev.entity,
                                            &pixel_clock[i]);
                if (ret)
                        u64 min_rate = 0;
                        long rate;
 
-                       for (j = VFE_LINE_RDI0; j < vfe->line_num; j++) {
+                       for (j = VFE_LINE_RDI0; j < vfe->res->line_num; j++) {
                                u32 tmp;
                                u8 bpp;
 
        int i, j;
        int ret;
 
-       for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) {
+       for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++) {
                ret = camss_get_pixel_clock(&vfe->line[i].subdev.entity,
                                            &pixel_clock[i]);
                if (ret)
                        u64 min_rate = 0;
                        unsigned long rate;
 
-                       for (j = VFE_LINE_RDI0; j < vfe->line_num; j++) {
+                       for (j = VFE_LINE_RDI0; j < vfe->res->line_num; j++) {
                                u32 tmp;
                                u8 bpp;
 
        mutex_lock(&vfe->power_lock);
 
        if (vfe->power_count == 0) {
-               ret = vfe->ops->pm_domain_on(vfe);
+               ret = vfe->res->hw_ops->pm_domain_on(vfe);
                if (ret < 0)
                        goto error_pm_domain;
 
 
                vfe_init_outputs(vfe);
 
-               vfe->ops->hw_version(vfe);
+               vfe->res->hw_ops->hw_version(vfe);
        } else {
                ret = vfe_check_clock_rates(vfe);
                if (ret < 0)
 error_pm_runtime_get:
        pm_runtime_put_sync(vfe->camss->dev);
 error_domain_off:
-       vfe->ops->pm_domain_off(vfe);
+       vfe->res->hw_ops->pm_domain_off(vfe);
 
 error_pm_domain:
        mutex_unlock(&vfe->power_lock);
        } else if (vfe->power_count == 1) {
                if (vfe->was_streaming) {
                        vfe->was_streaming = 0;
-                       vfe->ops->vfe_halt(vfe);
+                       vfe->res->hw_ops->vfe_halt(vfe);
                }
                camss_disable_clocks(vfe->nclocks, vfe->clock);
                pm_runtime_put_sync(vfe->camss->dev);
-               vfe->ops->pm_domain_off(vfe);
+               vfe->res->hw_ops->pm_domain_off(vfe);
        }
 
        vfe->power_count--;
 
        if (enable) {
                line->output.state = VFE_OUTPUT_RESERVED;
-               ret = vfe->ops->vfe_enable(line);
+               ret = vfe->res->hw_ops->vfe_enable(line);
                if (ret < 0)
                        dev_err(vfe->camss->dev,
                                "Failed to enable vfe outputs\n");
        } else {
-               ret = vfe->ops->vfe_disable(line);
+               ret = vfe->res->hw_ops->vfe_disable(line);
                if (ret < 0)
                        dev_err(vfe->camss->dev,
                                "Failed to disable vfe outputs\n");
        int i, j;
        int ret;
 
-       vfe->ops = res->ops;
-
-       if (!res->line_num)
+       if (!res->vfe.line_num)
                return -EINVAL;
 
+       vfe->res = &res->vfe;
+       vfe->res->hw_ops->subdev_init(dev, vfe);
+
        /* Power domain */
 
-       if (res->pd_name) {
+       if (res->vfe.pd_name) {
                vfe->genpd = dev_pm_domain_attach_by_name(camss->dev,
-                                                         res->pd_name);
+                                                         res->vfe.pd_name);
                if (IS_ERR(vfe->genpd)) {
                        ret = PTR_ERR(vfe->genpd);
                        return ret;
                }
        }
 
-       if (!vfe->genpd && res->has_pd) {
+       if (!vfe->genpd && res->vfe.has_pd) {
                /*
                 * Legacy magic index.
                 * Requires
                        return PTR_ERR(vfe->genpd);
        }
 
-       vfe->line_num = res->line_num;
-       vfe->ops->subdev_init(dev, vfe);
-
        /* Memory */
 
        vfe->base = devm_platform_ioremap_resource_byname(pdev, res->reg[0]);
        vfe->irq = ret;
        snprintf(vfe->irq_name, sizeof(vfe->irq_name), "%s_%s%d",
                 dev_name(dev), MSM_VFE_NAME, id);
-       ret = devm_request_irq(dev, vfe->irq, vfe->ops->isr,
+       ret = devm_request_irq(dev, vfe->irq, vfe->res->hw_ops->isr,
                               IRQF_TRIGGER_RISING, vfe->irq_name, vfe);
        if (ret < 0) {
                dev_err(dev, "request_irq failed: %d\n", ret);
        vfe->id = id;
        vfe->reg_update = 0;
 
-       for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) {
+       for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++) {
                struct vfe_line *l = &vfe->line[i];
 
                l->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
        int ret;
        int i;
 
-       for (i = 0; i < vfe->line_num; i++) {
+       for (i = 0; i < vfe->res->line_num; i++) {
                char name[32];
 
                sd = &vfe->line[i].subdev;
        mutex_destroy(&vfe->power_lock);
        mutex_destroy(&vfe->stream_lock);
 
-       for (i = 0; i < vfe->line_num; i++) {
+       for (i = 0; i < vfe->res->line_num; i++) {
                struct v4l2_subdev *sd = &vfe->line[i].subdev;
                struct camss_video *video_out = &vfe->line[i].video_out;
 
 
 bool vfe_is_lite(struct vfe_device *vfe)
 {
-       return vfe->camss->res->vfe_res[vfe->id].is_lite;
+       return vfe->camss->res->vfe_res[vfe->id].vfe.is_lite;
 }
 
        void (*wm_done)(struct vfe_device *vfe, u8 wm);
 };
 
+struct vfe_subdev_resources {
+       bool is_lite;
+       u8 line_num;
+       bool has_pd;
+       char *pd_name;
+       const struct vfe_hw_ops *hw_ops;
+};
+
 struct vfe_device {
        struct camss *camss;
        u8 id;
        spinlock_t output_lock;
        enum vfe_line_id wm_output_map[MSM_VFE_IMAGE_MASTERS_NUM];
        struct vfe_line line[VFE_LINE_NUM_MAX];
-       u8 line_num;
        u32 reg_update;
        u8 was_streaming;
-       const struct vfe_hw_ops *ops;
+       const struct vfe_subdev_resources *res;
        const struct vfe_hw_ops_gen1 *ops_gen1;
        struct vfe_isr_ops isr_ops;
        struct camss_video_ops video_ops;
 
                                { 100000000, 200000000 } },
                .reg = { "csiphy0", "csiphy0_clk_mux" },
                .interrupt = { "csiphy0" },
-               .ops = &csiphy_ops_2ph_1_0
+               .csiphy = {
+                       .hw_ops = &csiphy_ops_2ph_1_0
+               }
        },
 
        /* CSIPHY1 */
                                { 100000000, 200000000 } },
                .reg = { "csiphy1", "csiphy1_clk_mux" },
                .interrupt = { "csiphy1" },
-               .ops = &csiphy_ops_2ph_1_0
+               .csiphy = {
+                       .hw_ops = &csiphy_ops_2ph_1_0
+               }
        }
 };
 
                                { 0 } },
                .reg = { "csid0" },
                .interrupt = { "csid0" },
-               .ops = &csid_ops_4_1,
+               .csid = {
+                       .hw_ops = &csid_ops_4_1
+               }
        },
 
        /* CSID1 */
                                { 0 } },
                .reg = { "csid1" },
                .interrupt = { "csid1" },
-               .ops = &csid_ops_4_1,
+               .csid = {
+                       .hw_ops = &csid_ops_4_1
+               }
        },
 };
 
                   "csi1", "csi1_pix", "csi1_rdi" },
        .clock_for_reset = { "vfe0", "csi_vfe0" },
        .reg = { "ispif", "csi_clk_mux" },
-       .interrupt = { "ispif" }
-
+       .interrupt = { "ispif" },
 };
 
 static const struct camss_subdev_resources vfe_res_8x16[] = {
                                { 0 } },
                .reg = { "vfe0" },
                .interrupt = { "vfe0" },
-               .line_num = 3,
-               .ops = &vfe_ops_4_1
+               .vfe = {
+                       .line_num = 3,
+                       .hw_ops = &vfe_ops_4_1
+               }
        }
 };
 
                                { 100000000, 200000000, 266666667 } },
                .reg = { "csiphy0", "csiphy0_clk_mux" },
                .interrupt = { "csiphy0" },
-               .ops = &csiphy_ops_3ph_1_0
+               .csiphy = {
+                       .hw_ops = &csiphy_ops_3ph_1_0
+               }
        },
 
        /* CSIPHY1 */
                                { 100000000, 200000000, 266666667 } },
                .reg = { "csiphy1", "csiphy1_clk_mux" },
                .interrupt = { "csiphy1" },
-               .ops = &csiphy_ops_3ph_1_0
+               .csiphy = {
+                       .hw_ops = &csiphy_ops_3ph_1_0
+               }
        },
 
        /* CSIPHY2 */
                                { 100000000, 200000000, 266666667 } },
                .reg = { "csiphy2", "csiphy2_clk_mux" },
                .interrupt = { "csiphy2" },
-               .ops = &csiphy_ops_3ph_1_0
+               .csiphy = {
+                       .hw_ops = &csiphy_ops_3ph_1_0
+               }
        }
 };
 
                                { 0 } },
                .reg = { "csid0" },
                .interrupt = { "csid0" },
-               .ops = &csid_ops_4_7,
+               .csid = {
+                       .hw_ops = &csid_ops_4_7
+               }
        },
 
        /* CSID1 */
                                { 0 } },
                .reg = { "csid1" },
                .interrupt = { "csid1" },
-               .ops = &csid_ops_4_7,
+               .csid = {
+                       .hw_ops = &csid_ops_4_7
+               }
        },
 
        /* CSID2 */
                                { 0 } },
                .reg = { "csid2" },
                .interrupt = { "csid2" },
-               .ops = &csid_ops_4_7,
+               .csid = {
+                       .hw_ops = &csid_ops_4_7
+               }
        },
 
        /* CSID3 */
                                { 0 } },
                .reg = { "csid3" },
                .interrupt = { "csid3" },
-               .ops = &csid_ops_4_7,
+               .csid = {
+                       .hw_ops = &csid_ops_4_7
+               }
        }
 };
 
                   "csi3", "csi3_pix", "csi3_rdi" },
        .clock_for_reset = { "vfe0", "csi_vfe0", "vfe1", "csi_vfe1" },
        .reg = { "ispif", "csi_clk_mux" },
-       .interrupt = { "ispif" }
+       .interrupt = { "ispif" },
 };
 
 static const struct camss_subdev_resources vfe_res_8x96[] = {
                                { 0 } },
                .reg = { "vfe0" },
                .interrupt = { "vfe0" },
-               .line_num = 3,
-               .has_pd = true,
-               .ops = &vfe_ops_4_7
+               .vfe = {
+                       .line_num = 3,
+                       .has_pd = true,
+                       .hw_ops = &vfe_ops_4_7
+               }
        },
 
        /* VFE1 */
                                { 0 } },
                .reg = { "vfe1" },
                .interrupt = { "vfe1" },
-               .line_num = 3,
-               .has_pd = true,
-               .ops = &vfe_ops_4_7
+               .vfe = {
+                       .line_num = 3,
+                       .has_pd = true,
+                       .hw_ops = &vfe_ops_4_7
+               }
        }
 };
 
                                { 0 } },
                .reg = { "csiphy0", "csiphy0_clk_mux" },
                .interrupt = { "csiphy0" },
-               .ops = &csiphy_ops_3ph_1_0
+               .csiphy = {
+                       .hw_ops = &csiphy_ops_3ph_1_0
+               }
        },
 
        /* CSIPHY1 */
                                { 0 } },
                .reg = { "csiphy1", "csiphy1_clk_mux" },
                .interrupt = { "csiphy1" },
-               .ops = &csiphy_ops_3ph_1_0
+               .csiphy = {
+                       .hw_ops = &csiphy_ops_3ph_1_0
+               }
        },
 
        /* CSIPHY2 */
                                { 0 } },
                .reg = { "csiphy2", "csiphy2_clk_mux" },
                .interrupt = { "csiphy2" },
-               .ops = &csiphy_ops_3ph_1_0
+               .csiphy = {
+                       .hw_ops = &csiphy_ops_3ph_1_0
+               }
        }
 };
 
                                { 0 } },
                .reg = { "csid0" },
                .interrupt = { "csid0" },
-               .ops = &csid_ops_4_7,
+               .csid = {
+                       .hw_ops = &csid_ops_4_7
+               }
        },
 
        /* CSID1 */
                                { 0 } },
                .reg = { "csid1" },
                .interrupt = { "csid1" },
-               .ops = &csid_ops_4_7,
+               .csid = {
+                       .hw_ops = &csid_ops_4_7
+               }
        },
 
        /* CSID2 */
                                { 0 } },
                .reg = { "csid2" },
                .interrupt = { "csid2" },
-               .ops = &csid_ops_4_7,
+               .csid = {
+                       .hw_ops = &csid_ops_4_7
+               }
        },
 
        /* CSID3 */
                                { 0 } },
                .reg = { "csid3" },
                .interrupt = { "csid3" },
-               .ops = &csid_ops_4_7,
+               .csid = {
+                       .hw_ops = &csid_ops_4_7
+               }
        }
 };
 
                   "csi3", "csi3_pix", "csi3_rdi" },
        .clock_for_reset = { "vfe0", "csi_vfe0", "vfe1", "csi_vfe1" },
        .reg = { "ispif", "csi_clk_mux" },
-       .interrupt = { "ispif" }
+       .interrupt = { "ispif" },
 };
 
 static const struct camss_subdev_resources vfe_res_660[] = {
                                { 0 } },
                .reg = { "vfe0" },
                .interrupt = { "vfe0" },
-               .line_num = 3,
-               .has_pd = true,
-               .ops = &vfe_ops_4_8
+               .vfe = {
+                       .line_num = 3,
+                       .has_pd = true,
+                       .hw_ops = &vfe_ops_4_8
+               }
        },
 
        /* VFE1 */
                                { 0 } },
                .reg = { "vfe1" },
                .interrupt = { "vfe1" },
-               .line_num = 3,
-               .has_pd = true,
-               .ops = &vfe_ops_4_8
+               .vfe = {
+                       .line_num = 3,
+                       .has_pd = true,
+                       .hw_ops = &vfe_ops_4_8
+               }
        }
 };
 
                                { 19200000, 240000000, 269333333 } },
                .reg = { "csiphy0" },
                .interrupt = { "csiphy0" },
-               .ops = &csiphy_ops_3ph_1_0
+               .csiphy = {
+                       .hw_ops = &csiphy_ops_3ph_1_0
+               }
        },
 
        /* CSIPHY1 */
                                { 19200000, 240000000, 269333333 } },
                .reg = { "csiphy1" },
                .interrupt = { "csiphy1" },
-               .ops = &csiphy_ops_3ph_1_0
+               .csiphy = {
+                       .hw_ops = &csiphy_ops_3ph_1_0
+               }
        },
 
        /* CSIPHY2 */
                                { 19200000, 240000000, 269333333 } },
                .reg = { "csiphy2" },
                .interrupt = { "csiphy2" },
-               .ops = &csiphy_ops_3ph_1_0
+               .csiphy = {
+                       .hw_ops = &csiphy_ops_3ph_1_0
+               }
        },
 
        /* CSIPHY3 */
                                { 19200000, 240000000, 269333333 } },
                .reg = { "csiphy3" },
                .interrupt = { "csiphy3" },
-               .ops = &csiphy_ops_3ph_1_0
+               .csiphy = {
+                       .hw_ops = &csiphy_ops_3ph_1_0
+               }
        }
 };
 
                                { 384000000 } },
                .reg = { "csid0" },
                .interrupt = { "csid0" },
-               .ops = &csid_ops_gen2
+               .csid = {
+                       .hw_ops = &csid_ops_gen2
+               }
        },
 
        /* CSID1 */
                                { 384000000 } },
                .reg = { "csid1" },
                .interrupt = { "csid1" },
-               .ops = &csid_ops_gen2
+               .csid = {
+                       .hw_ops = &csid_ops_gen2
+               }
        },
 
        /* CSID2 */
                                { 384000000 } },
                .reg = { "csid2" },
                .interrupt = { "csid2" },
-               .is_lite = true,
-               .ops = &csid_ops_gen2
+               .csid = {
+                       .is_lite = true,
+                       .hw_ops = &csid_ops_gen2
+               }
        }
 };
 
                                { 384000000 } },
                .reg = { "vfe0" },
                .interrupt = { "vfe0" },
-               .line_num = 4,
-               .has_pd = true,
-               .ops = &vfe_ops_170
+               .vfe = {
+                       .line_num = 4,
+                       .has_pd = true,
+                       .hw_ops = &vfe_ops_170
+               }
        },
 
        /* VFE1 */
                                { 384000000 } },
                .reg = { "vfe1" },
                .interrupt = { "vfe1" },
-               .line_num = 4,
-               .has_pd = true,
-               .ops = &vfe_ops_170
+               .vfe = {
+                       .line_num = 4,
+                       .has_pd = true,
+                       .hw_ops = &vfe_ops_170
+               }
        },
 
        /* VFE-lite */
                                { 384000000 } },
                .reg = { "vfe_lite" },
                .interrupt = { "vfe_lite" },
-               .is_lite = true,
-               .line_num = 4,
-               .ops = &vfe_ops_170
+               .vfe = {
+                       .is_lite = true,
+                       .line_num = 4,
+                       .hw_ops = &vfe_ops_170
+               }
        }
 };
 
                                { 300000000 } },
                .reg = { "csiphy0" },
                .interrupt = { "csiphy0" },
-               .ops = &csiphy_ops_3ph_1_0
+               .csiphy = {
+                       .hw_ops = &csiphy_ops_3ph_1_0
+               }
        },
        /* CSIPHY1 */
        {
                                { 300000000 } },
                .reg = { "csiphy1" },
                .interrupt = { "csiphy1" },
-               .ops = &csiphy_ops_3ph_1_0
+               .csiphy = {
+                       .hw_ops = &csiphy_ops_3ph_1_0
+               }
        },
        /* CSIPHY2 */
        {
                                { 300000000 } },
                .reg = { "csiphy2" },
                .interrupt = { "csiphy2" },
-               .ops = &csiphy_ops_3ph_1_0
+               .csiphy = {
+                       .hw_ops = &csiphy_ops_3ph_1_0
+               }
        },
        /* CSIPHY3 */
        {
                                { 300000000 } },
                .reg = { "csiphy3" },
                .interrupt = { "csiphy3" },
-               .ops = &csiphy_ops_3ph_1_0
+               .csiphy = {
+                       .hw_ops = &csiphy_ops_3ph_1_0
+               }
        },
        /* CSIPHY4 */
        {
                                { 300000000 } },
                .reg = { "csiphy4" },
                .interrupt = { "csiphy4" },
-               .ops = &csiphy_ops_3ph_1_0
+               .csiphy = {
+                       .hw_ops = &csiphy_ops_3ph_1_0
+               }
        },
        /* CSIPHY5 */
        {
                                { 300000000 } },
                .reg = { "csiphy5" },
                .interrupt = { "csiphy5" },
-               .ops = &csiphy_ops_3ph_1_0
+               .csiphy = {
+                       .hw_ops = &csiphy_ops_3ph_1_0
+               }
        }
 };
 
                                { 0 } },
                .reg = { "csid0" },
                .interrupt = { "csid0" },
-               .ops = &csid_ops_gen2
+               .csid = {
+                       .hw_ops = &csid_ops_gen2
+               }
        },
        /* CSID1 */
        {
                                { 0 } },
                .reg = { "csid1" },
                .interrupt = { "csid1" },
-               .ops = &csid_ops_gen2
+               .csid = {
+                       .hw_ops = &csid_ops_gen2
+               }
        },
        /* CSID2 */
        {
                                { 0 } },
                .reg = { "csid2" },
                .interrupt = { "csid2" },
-               .is_lite = true,
-               .ops = &csid_ops_gen2
+               .csid = {
+                       .is_lite = true,
+                       .hw_ops = &csid_ops_gen2
+               }
        },
        /* CSID3 */
        {
                                { 0 } },
                .reg = { "csid3" },
                .interrupt = { "csid3" },
-               .is_lite = true,
-               .ops = &csid_ops_gen2
+               .csid = {
+                       .is_lite = true,
+                       .hw_ops = &csid_ops_gen2
+               }
        }
 };
 
                                { 0 } },
                .reg = { "vfe0" },
                .interrupt = { "vfe0" },
-               .pd_name = "ife0",
-               .line_num = 3,
-               .has_pd = true,
-               .ops = &vfe_ops_480
+               .vfe = {
+                       .line_num = 3,
+                       .has_pd = true,
+                       .pd_name = "ife0",
+                       .hw_ops = &vfe_ops_480
+               }
        },
        /* VFE1 */
        {
                                { 0 } },
                .reg = { "vfe1" },
                .interrupt = { "vfe1" },
-               .pd_name = "ife1",
-               .line_num = 3,
-               .has_pd = true,
-               .ops = &vfe_ops_480
+               .vfe = {
+                       .line_num = 3,
+                       .has_pd = true,
+                       .pd_name = "ife1",
+                       .hw_ops = &vfe_ops_480
+               }
        },
        /* VFE2 (lite) */
        {
                                { 0 } },
                .reg = { "vfe_lite0" },
                .interrupt = { "vfe_lite0" },
-               .is_lite = true,
-               .line_num = 4,
-               .ops = &vfe_ops_480
+               .vfe = {
+                       .is_lite = true,
+                       .line_num = 4,
+                       .hw_ops = &vfe_ops_480
+               }
        },
        /* VFE3 (lite) */
        {
                                { 0 } },
                .reg = { "vfe_lite1" },
                .interrupt = { "vfe_lite1" },
-               .is_lite = true,
-               .line_num = 4,
-               .ops = &vfe_ops_480
+               .vfe = {
+                       .is_lite = true,
+                       .line_num = 4,
+                       .hw_ops = &vfe_ops_480
+               }
        },
 };
 
                                { 300000000 } },
                .reg = { "csiphy0" },
                .interrupt = { "csiphy0" },
-               .ops = &csiphy_ops_3ph_1_0
+               .csiphy = {
+                       .hw_ops = &csiphy_ops_3ph_1_0
+               }
        },
        /* CSIPHY1 */
        {
                                { 300000000 } },
                .reg = { "csiphy1" },
                .interrupt = { "csiphy1" },
-               .ops = &csiphy_ops_3ph_1_0
+               .csiphy = {
+                       .hw_ops = &csiphy_ops_3ph_1_0
+               }
        },
        /* CSIPHY2 */
        {
                                { 300000000 } },
                .reg = { "csiphy2" },
                .interrupt = { "csiphy2" },
-               .ops = &csiphy_ops_3ph_1_0
+               .csiphy = {
+                       .hw_ops = &csiphy_ops_3ph_1_0
+               }
        },
        /* CSIPHY3 */
        {
                                { 300000000 } },
                .reg = { "csiphy3" },
                .interrupt = { "csiphy3" },
-               .ops = &csiphy_ops_3ph_1_0
+               .csiphy = {
+                       .hw_ops = &csiphy_ops_3ph_1_0
+               }
        },
 };
 
                                { 0 } },
                .reg = { "csid0" },
                .interrupt = { "csid0" },
-               .ops = &csid_ops_gen2
+               .csid = {
+                       .hw_ops = &csid_ops_gen2
+               }
        },
        /* CSID1 */
        {
                                { 0 } },
                .reg = { "csid1" },
                .interrupt = { "csid1" },
-               .ops = &csid_ops_gen2
+               .csid = {
+                       .hw_ops = &csid_ops_gen2
+               }
        },
        /* CSID2 */
        {
                                { 0 } },
                .reg = { "csid2" },
                .interrupt = { "csid2" },
-               .ops = &csid_ops_gen2
+               .csid = {
+                       .hw_ops = &csid_ops_gen2
+               }
        },
        /* CSID3 */
        {
                                { 0 } },
                .reg = { "csid3" },
                .interrupt = { "csid3" },
-               .ops = &csid_ops_gen2
+               .csid = {
+                       .hw_ops = &csid_ops_gen2
+               }
        },
        /* CSID_LITE0 */
        {
                                { 0 }, },
                .reg = { "csid0_lite" },
                .interrupt = { "csid0_lite" },
-               .is_lite = true,
-               .ops = &csid_ops_gen2
+               .csid = {
+                       .is_lite = true,
+                       .hw_ops = &csid_ops_gen2
+               }
        },
        /* CSID_LITE1 */
        {
                                { 0 }, },
                .reg = { "csid1_lite" },
                .interrupt = { "csid1_lite" },
-               .is_lite = true,
-               .ops = &csid_ops_gen2
+               .csid = {
+                       .is_lite = true,
+                       .hw_ops = &csid_ops_gen2
+               }
        },
        /* CSID_LITE2 */
        {
                                { 0 }, },
                .reg = { "csid2_lite" },
                .interrupt = { "csid2_lite" },
-               .is_lite = true,
-               .ops = &csid_ops_gen2
+               .csid = {
+                       .is_lite = true,
+                       .hw_ops = &csid_ops_gen2
+               }
        },
        /* CSID_LITE3 */
        {
                                { 0 }, },
                .reg = { "csid3_lite" },
                .interrupt = { "csid3_lite" },
-               .is_lite = true,
-               .ops = &csid_ops_gen2
+               .csid = {
+                       .is_lite = true,
+                       .hw_ops = &csid_ops_gen2
+               }
        }
 };
 
                                { 0 }, },
                .reg = { "vfe0" },
                .interrupt = { "vfe0" },
-               .pd_name = "ife0",
-               .line_num = 4,
-               .ops = &vfe_ops_170
+               .vfe = {
+                       .line_num = 4,
+                       .pd_name = "ife0",
+                       .hw_ops = &vfe_ops_170
+               }
        },
        /* VFE1 */
        {
                                { 0 }, },
                .reg = { "vfe1" },
                .interrupt = { "vfe1" },
-               .pd_name = "ife1",
-               .line_num = 4,
-               .ops = &vfe_ops_170
+               .vfe = {
+                       .line_num = 4,
+                       .pd_name = "ife1",
+                       .hw_ops = &vfe_ops_170
+               }
        },
        /* VFE2 */
        {
                                { 0 }, },
                .reg = { "vfe2" },
                .interrupt = { "vfe2" },
-               .pd_name = "ife2",
-               .line_num = 4,
-               .ops = &vfe_ops_170
+               .vfe = {
+                       .line_num = 4,
+                       .pd_name = "ife2",
+                       .hw_ops = &vfe_ops_170
+               }
        },
        /* VFE3 */
        {
                                { 0 }, },
                .reg = { "vfe3" },
                .interrupt = { "vfe3" },
-               .pd_name = "ife3",
-               .line_num = 4,
-               .ops = &vfe_ops_170
+               .vfe = {
+                       .line_num = 4,
+                       .pd_name = "ife3",
+                       .hw_ops = &vfe_ops_170
+               }
        },
        /* VFE_LITE_0 */
        {
                                { 320000000, 400000000, 480000000, 600000000 }, },
                .reg = { "vfe_lite0" },
                .interrupt = { "vfe_lite0" },
-               .is_lite = true,
-               .line_num = 4,
-               .ops = &vfe_ops_170
+               .vfe = {
+                       .is_lite = true,
+                       .line_num = 4,
+                       .hw_ops = &vfe_ops_170
+               }
        },
        /* VFE_LITE_1 */
        {
                                { 320000000, 400000000, 480000000, 600000000 }, },
                .reg = { "vfe_lite1" },
                .interrupt = { "vfe_lite1" },
-               .is_lite = true,
-               .line_num = 4,
-               .ops = &vfe_ops_170
+               .vfe = {
+                       .is_lite = true,
+                       .line_num = 4,
+                       .hw_ops = &vfe_ops_170
+               }
        },
        /* VFE_LITE_2 */
        {
                                { 320000000, 400000000, 480000000, 600000000, }, },
                .reg = { "vfe_lite2" },
                .interrupt = { "vfe_lite2" },
-               .is_lite = true,
-               .line_num = 4,
-               .ops = &vfe_ops_170
+               .vfe = {
+                       .is_lite = true,
+                       .line_num = 4,
+                       .hw_ops = &vfe_ops_170
+               }
        },
        /* VFE_LITE_3 */
        {
                                { 320000000, 400000000, 480000000, 600000000 }, },
                .reg = { "vfe_lite3" },
                .interrupt = { "vfe_lite3" },
-               .is_lite = true,
-               .line_num = 4,
-               .ops = &vfe_ops_170
+               .vfe = {
+                       .is_lite = true,
+                       .line_num = 4,
+                       .hw_ops = &vfe_ops_170
+               }
        },
 };
 
        if (id < camss->res->vfe_num) {
                struct vfe_device *vfe = &camss->vfe[id];
 
-               ret = vfe->ops->pm_domain_on(vfe);
+               ret = vfe->res->hw_ops->pm_domain_on(vfe);
        }
 
        return ret;
        if (id < camss->res->vfe_num) {
                struct vfe_device *vfe = &camss->vfe[id];
 
-               vfe->ops->pm_domain_off(vfe);
+               vfe->res->hw_ops->pm_domain_off(vfe);
        }
 }
 
 
                for (i = 0; i < camss->ispif->line_num; i++)
                        for (k = 0; k < camss->res->vfe_num; k++)
-                               for (j = 0; j < camss->vfe[k].line_num; j++) {
+                               for (j = 0; j < camss->vfe[k].res->line_num; j++) {
                                        struct v4l2_subdev *ispif = &camss->ispif->line[i].subdev;
                                        struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev;
 
        } else {
                for (i = 0; i < camss->res->csid_num; i++)
                        for (k = 0; k < camss->res->vfe_num; k++)
-                               for (j = 0; j < camss->vfe[k].line_num; j++) {
+                               for (j = 0; j < camss->vfe[k].res->line_num; j++) {
                                        struct v4l2_subdev *csid = &camss->csid[i].subdev;
                                        struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev;
 
 
        /* count the # of VFEs which have flagged power-domain */
        for (vfepd_num = i = 0; i < camss->res->vfe_num; i++) {
-               if (res->vfe_res[i].has_pd)
+               if (res->vfe_res[i].vfe.has_pd)
                        vfepd_num++;
        }
 
 
        u32 clock_rate[CAMSS_RES_MAX][CAMSS_RES_MAX];
        char *reg[CAMSS_RES_MAX];
        char *interrupt[CAMSS_RES_MAX];
-       char *pd_name;
-       u8 line_num;
-       bool has_pd;
-       bool is_lite;
-       const void *ops;
+       union {
+               struct csiphy_subdev_resources csiphy;
+               struct csid_subdev_resources csid;
+               struct vfe_subdev_resources vfe;
+       };
 };
 
 struct icc_bw_tbl {