sensor->link_freq = v4l2_ctrl_new_int_menu(
                &sensor->src->ctrl_handler, &ccs_ctrl_ops,
                V4L2_CID_LINK_FREQ, __fls(*valid_link_freqs),
-               __ffs(*valid_link_freqs), sensor->hwcfg->op_sys_clock);
+               __ffs(*valid_link_freqs), sensor->hwcfg.op_sys_clock);
 
        return sensor->src->ctrl_handler.error;
 }
 
                pll->bits_per_pixel = f->compressed;
 
-               for (j = 0; sensor->hwcfg->op_sys_clock[j]; j++) {
-                       pll->link_freq = sensor->hwcfg->op_sys_clock[j];
+               for (j = 0; sensor->hwcfg.op_sys_clock[j]; j++) {
+                       pll->link_freq = sensor->hwcfg.op_sys_clock[j];
 
                        rval = ccs_pll_try(sensor, pll);
                        dev_dbg(&client->dev, "link freq %u Hz, bpp %u %s\n",
        int rval;
        u32 val;
 
-       client->addr = sensor->hwcfg->i2c_addr_dfl;
+       client->addr = sensor->hwcfg.i2c_addr_dfl;
 
        rval = ccs_write(sensor, CCI_ADDRESS_CTRL,
-                        sensor->hwcfg->i2c_addr_alt << 1);
+                        sensor->hwcfg.i2c_addr_alt << 1);
        if (rval)
                return rval;
 
-       client->addr = sensor->hwcfg->i2c_addr_alt;
+       client->addr = sensor->hwcfg.i2c_addr_alt;
 
        /* verify addr change went ok */
        rval = ccs_read(sensor, CCI_ADDRESS_CTRL, &val);
        if (rval)
                return rval;
 
-       if (val != sensor->hwcfg->i2c_addr_alt << 1)
+       if (val != sensor->hwcfg.i2c_addr_alt << 1)
                return -ENODEV;
 
        return 0;
 static int ccs_setup_flash_strobe(struct ccs_sensor *sensor)
 {
        struct ccs_flash_strobe_parms *strobe_setup;
-       unsigned int ext_freq = sensor->hwcfg->ext_clk;
+       unsigned int ext_freq = sensor->hwcfg.ext_clk;
        u32 tmp;
        u32 strobe_adjustment;
        u32 strobe_width_high_rs;
        int rval;
 
-       strobe_setup = sensor->hwcfg->strobe_setup;
+       strobe_setup = sensor->hwcfg.strobe_setup;
 
        /*
         * How to calculate registers related to strobe length. Please
        rval = ccs_write(sensor, FLASH_TRIGGER_RS, strobe_setup->trigger);
 
 out:
-       sensor->hwcfg->strobe_setup->trigger = 0;
+       sensor->hwcfg.strobe_setup->trigger = 0;
 
        return rval;
 }
        gpiod_set_value(sensor->reset, 0);
        gpiod_set_value(sensor->xshutdown, 1);
 
-       sleep = SMIAPP_RESET_DELAY(sensor->hwcfg->ext_clk);
+       sleep = SMIAPP_RESET_DELAY(sensor->hwcfg.ext_clk);
        usleep_range(sleep, sleep);
 
        /*
         * is found.
         */
 
-       if (sensor->hwcfg->i2c_addr_alt) {
+       if (sensor->hwcfg.i2c_addr_alt) {
                rval = ccs_change_cci_addr(sensor);
                if (rval) {
                        dev_err(dev, "cci address change error\n");
                goto out_cci_addr_fail;
        }
 
-       if (sensor->hwcfg->i2c_addr_alt) {
+       if (sensor->hwcfg.i2c_addr_alt) {
                rval = ccs_change_cci_addr(sensor);
                if (rval) {
                        dev_err(dev, "cci address change error\n");
        }
 
        rval = ccs_write(sensor, EXTCLK_FREQUENCY_MHZ,
-                        sensor->hwcfg->ext_clk / (1000000 / (1 << 8)));
+                        sensor->hwcfg.ext_clk / (1000000 / (1 << 8)));
        if (rval) {
                dev_err(dev, "extclk frequency set failed\n");
                goto out_cci_addr_fail;
        }
 
-       rval = ccs_write(sensor, CSI_LANE_MODE, sensor->hwcfg->lanes - 1);
+       rval = ccs_write(sensor, CSI_LANE_MODE, sensor->hwcfg.lanes - 1);
        if (rval) {
                dev_err(dev, "csi lane mode set failed\n");
                goto out_cci_addr_fail;
        }
 
        rval = ccs_write(sensor, CSI_SIGNALING_MODE,
-                        sensor->hwcfg->csi_signalling_mode);
+                        sensor->hwcfg.csi_signalling_mode);
        if (rval) {
                dev_err(dev, "csi signalling mode set failed\n");
                goto out_cci_addr_fail;
         * really see a power off and next time the cci address change
         * will fail. So do a soft reset explicitly here.
         */
-       if (sensor->hwcfg->i2c_addr_alt)
+       if (sensor->hwcfg.i2c_addr_alt)
                ccs_write(sensor, SOFTWARE_RESET, CCS_SOFTWARE_RESET_ON);
 
        gpiod_set_value(sensor->reset, 1);
        if (CCS_LIM(sensor, FLASH_MODE_CAPABILITY) &
            (CCS_FLASH_MODE_CAPABILITY_SINGLE_STROBE |
             SMIAPP_FLASH_MODE_CAPABILITY_MULTIPLE_STROBE) &&
-           sensor->hwcfg->strobe_setup != NULL &&
-           sensor->hwcfg->strobe_setup->trigger != 0) {
+           sensor->hwcfg.strobe_setup != NULL &&
+           sensor->hwcfg.strobe_setup->trigger != 0) {
                rval = ccs_setup_flash_strobe(sensor);
                if (rval)
                        goto out;
        return rval;
 }
 
-static struct ccs_hwconfig *ccs_get_hwconfig(struct device *dev)
+static int ccs_get_hwconfig(struct ccs_sensor *sensor, struct device *dev)
 {
-       struct ccs_hwconfig *hwcfg;
+       struct ccs_hwconfig *hwcfg = &sensor->hwcfg;
        struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 };
        struct fwnode_handle *ep;
        struct fwnode_handle *fwnode = dev_fwnode(dev);
 
        ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
        if (!ep)
-               return NULL;
+               return -ENODEV;
 
        bus_cfg.bus_type = V4L2_MBUS_CSI2_DPHY;
        rval = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
        if (rval)
                goto out_err;
 
-       hwcfg = devm_kzalloc(dev, sizeof(*hwcfg), GFP_KERNEL);
-       if (!hwcfg)
-               goto out_err;
-
        switch (bus_cfg.bus_type) {
        case V4L2_MBUS_CSI2_DPHY:
                hwcfg->csi_signalling_mode = CCS_CSI_SIGNALING_MODE_CSI_2_DPHY;
                break;
        default:
                dev_err(dev, "unsupported bus %u\n", bus_cfg.bus_type);
+               rval = -EINVAL;
                goto out_err;
        }
 
                        break;
                default:
                        dev_err(dev, "invalid rotation %u\n", rotation);
+                       rval = -EINVAL;
                        goto out_err;
                }
        }
 
        if (!bus_cfg.nr_of_link_frequencies) {
                dev_warn(dev, "no link frequencies defined\n");
+               rval = -EINVAL;
                goto out_err;
        }
 
        hwcfg->op_sys_clock = devm_kcalloc(
                dev, bus_cfg.nr_of_link_frequencies + 1 /* guardian */,
                sizeof(*hwcfg->op_sys_clock), GFP_KERNEL);
-       if (!hwcfg->op_sys_clock)
+       if (!hwcfg->op_sys_clock) {
+               rval = -ENOMEM;
                goto out_err;
+       }
 
        for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
                hwcfg->op_sys_clock[i] = bus_cfg.link_frequencies[i];
 
        v4l2_fwnode_endpoint_free(&bus_cfg);
        fwnode_handle_put(ep);
-       return hwcfg;
+
+       return 0;
 
 out_err:
        v4l2_fwnode_endpoint_free(&bus_cfg);
        fwnode_handle_put(ep);
-       return NULL;
+
+       return rval;
 }
 
 static int ccs_probe(struct i2c_client *client)
 {
        struct ccs_sensor *sensor;
-       struct ccs_hwconfig *hwcfg = ccs_get_hwconfig(&client->dev);
        unsigned int i;
        int rval;
 
-       if (hwcfg == NULL)
-               return -ENODEV;
-
        sensor = devm_kzalloc(&client->dev, sizeof(*sensor), GFP_KERNEL);
        if (sensor == NULL)
                return -ENOMEM;
 
-       sensor->hwcfg = hwcfg;
+       rval = ccs_get_hwconfig(sensor, &client->dev);
+       if (rval)
+               return rval;
+
        sensor->src = &sensor->ssds[sensor->ssds_used];
 
        v4l2_i2c_subdev_init(&sensor->src->sd, client, &ccs_ops);
        }
 
        if (sensor->ext_clk) {
-               if (sensor->hwcfg->ext_clk) {
+               if (sensor->hwcfg.ext_clk) {
                        unsigned long rate;
 
                        rval = clk_set_rate(sensor->ext_clk,
-                                           sensor->hwcfg->ext_clk);
+                                           sensor->hwcfg.ext_clk);
                        if (rval < 0) {
                                dev_err(&client->dev,
                                        "unable to set clock freq to %u\n",
-                                       sensor->hwcfg->ext_clk);
+                                       sensor->hwcfg.ext_clk);
                                return rval;
                        }
 
                        rate = clk_get_rate(sensor->ext_clk);
-                       if (rate != sensor->hwcfg->ext_clk) {
+                       if (rate != sensor->hwcfg.ext_clk) {
                                dev_err(&client->dev,
                                        "can't set clock freq, asked for %u but got %lu\n",
-                                       sensor->hwcfg->ext_clk, rate);
+                                       sensor->hwcfg.ext_clk, rate);
                                return rval;
                        }
                } else {
-                       sensor->hwcfg->ext_clk = clk_get_rate(sensor->ext_clk);
+                       sensor->hwcfg.ext_clk = clk_get_rate(sensor->ext_clk);
                        dev_dbg(&client->dev, "obtained clock freq %u\n",
-                               sensor->hwcfg->ext_clk);
+                               sensor->hwcfg.ext_clk);
                }
-       } else if (sensor->hwcfg->ext_clk) {
+       } else if (sensor->hwcfg.ext_clk) {
                dev_dbg(&client->dev, "assuming clock freq %u\n",
-                       sensor->hwcfg->ext_clk);
+                       sensor->hwcfg.ext_clk);
        } else {
                dev_err(&client->dev, "unable to obtain clock freq\n");
                return -EINVAL;
         *
         * Rotation also changes the bayer pattern.
         */
-       if (sensor->hwcfg->module_board_orient ==
+       if (sensor->hwcfg.module_board_orient ==
            CCS_MODULE_BOARD_ORIENT_180)
                sensor->hvflip_inv_mask =
                        CCS_IMAGE_ORIENTATION_HORIZONTAL_MIRROR |
 
        /* prepare PLL configuration input values */
        sensor->pll.bus_type = SMIAPP_PLL_BUS_TYPE_CSI2;
-       sensor->pll.csi2.lanes = sensor->hwcfg->lanes;
-       sensor->pll.ext_clk_freq_hz = sensor->hwcfg->ext_clk;
+       sensor->pll.csi2.lanes = sensor->hwcfg.lanes;
+       sensor->pll.ext_clk_freq_hz = sensor->hwcfg.ext_clk;
        sensor->pll.scale_n = CCS_LIM(sensor, SCALER_N_MIN);
 
        ccs_create_subdev(sensor, sensor->scaler, " scaler", 2,