Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 207dc3ed authored by Jigarkumar Zala's avatar Jigarkumar Zala Committed by Venkat Chinta
Browse files

msm: camera: Fix power related issues across sensor modules



Assign the power settings pointer to null after freeing it
and reset the power settings size variable to 0. Free power
settings if the sensor is in correct state. Add check in
acquire device to verify if the device has been probed
successfully before acquire.

Change-Id: I73f795fd0d8f0c3f17d49d2895c896bc6d349eea
Signed-off-by: default avatarJigarkumar Zala <jzala@codeaurora.org>
Signed-off-by: default avatarVishalsingh Hajeri <vhajeri@codeaurora.org>
Signed-off-by: default avatarVenkat Chinta <vchinta@codeaurora.org>
parent f09e00fd
Loading
Loading
Loading
Loading
+17 −1
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ int32_t cam_actuator_construct_default_power_setting(
free_power_settings:
	kfree(power_info->power_setting);
	power_info->power_setting = NULL;
	power_info->power_setting_size = 0;
	return rc;
}

@@ -659,6 +660,8 @@ void cam_actuator_shutdown(struct cam_actuator_ctrl_t *a_ctrl)
	kfree(power_info->power_down_setting);
	power_info->power_setting = NULL;
	power_info->power_down_setting = NULL;
	power_info->power_setting_size = 0;
	power_info->power_down_setting_size = 0;

	a_ctrl->cam_act_state = CAM_ACTUATOR_INIT;
}
@@ -668,12 +671,19 @@ int32_t cam_actuator_driver_cmd(struct cam_actuator_ctrl_t *a_ctrl,
{
	int rc = 0;
	struct cam_control *cmd = (struct cam_control *)arg;
	struct cam_actuator_soc_private *soc_private = NULL;
	struct cam_sensor_power_ctrl_t  *power_info = NULL;

	if (!a_ctrl || !cmd) {
		CAM_ERR(CAM_ACTUATOR, "Invalid Args");
		return -EINVAL;
	}

	soc_private =
		(struct cam_actuator_soc_private *)a_ctrl->soc_info.soc_private;

	power_info = &soc_private->power_info;

	if (cmd->handle_type != CAM_HANDLE_USER_POINTER) {
		CAM_ERR(CAM_ACTUATOR, "Invalid handle type: %d",
			cmd->handle_type);
@@ -756,6 +766,12 @@ int32_t cam_actuator_driver_cmd(struct cam_actuator_ctrl_t *a_ctrl,
		a_ctrl->bridge_intf.link_hdl = -1;
		a_ctrl->bridge_intf.session_hdl = -1;
		a_ctrl->cam_act_state = CAM_ACTUATOR_INIT;
		kfree(power_info->power_setting);
		kfree(power_info->power_down_setting);
		power_info->power_setting = NULL;
		power_info->power_down_setting = NULL;
		power_info->power_down_setting_size = 0;
		power_info->power_setting_size = 0;
	}
		break;
	case CAM_QUERY_CAP: {
+4 −0
Original line number Diff line number Diff line
@@ -785,6 +785,8 @@ static int32_t cam_eeprom_pkt_parse(struct cam_eeprom_ctrl_t *e_ctrl, void *arg)
		kfree(power_info->power_down_setting);
		power_info->power_setting = NULL;
		power_info->power_down_setting = NULL;
		power_info->power_setting_size = 0;
		power_info->power_down_setting_size = 0;
		e_ctrl->cal_data.num_data = 0;
		e_ctrl->cal_data.num_map = 0;
		break;
@@ -838,6 +840,8 @@ void cam_eeprom_shutdown(struct cam_eeprom_ctrl_t *e_ctrl)
		kfree(power_info->power_down_setting);
		power_info->power_setting = NULL;
		power_info->power_down_setting = NULL;
		power_info->power_setting_size = 0;
		power_info->power_down_setting_size = 0;
	}

	e_ctrl->cam_eeprom_state = CAM_EEPROM_INIT;
+22 −7
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ int32_t cam_ois_construct_default_power_setting(
free_power_settings:
	kfree(power_info->power_setting);
	power_info->power_setting = NULL;
	power_info->power_setting_size = 0;
	return rc;
}

@@ -640,8 +641,7 @@ void cam_ois_shutdown(struct cam_ois_ctrl_t *o_ctrl)
	int rc = 0;
	struct cam_ois_soc_private *soc_private =
		(struct cam_ois_soc_private *)o_ctrl->soc_info.soc_private;
	struct cam_sensor_power_ctrl_t *power_info =
		&soc_private->power_info;
	struct cam_sensor_power_ctrl_t *power_info = &soc_private->power_info;

	if (o_ctrl->cam_ois_state == CAM_OIS_INIT)
		return;
@@ -666,6 +666,8 @@ void cam_ois_shutdown(struct cam_ois_ctrl_t *o_ctrl)
	kfree(power_info->power_down_setting);
	power_info->power_setting = NULL;
	power_info->power_down_setting = NULL;
	power_info->power_down_setting_size = 0;
	power_info->power_setting_size = 0;

	o_ctrl->cam_ois_state = CAM_OIS_INIT;
}
@@ -682,8 +684,10 @@ int cam_ois_driver_cmd(struct cam_ois_ctrl_t *o_ctrl, void *arg)
	int                              rc = 0;
	struct cam_ois_query_cap_t       ois_cap = {0};
	struct cam_control              *cmd = (struct cam_control *)arg;
	struct cam_ois_soc_private      *soc_private = NULL;
	struct cam_sensor_power_ctrl_t  *power_info = NULL;

	if (!o_ctrl || !arg) {
	if (!o_ctrl || !cmd) {
		CAM_ERR(CAM_OIS, "Invalid arguments");
		return -EINVAL;
	}
@@ -694,6 +698,10 @@ int cam_ois_driver_cmd(struct cam_ois_ctrl_t *o_ctrl, void *arg)
		return -EINVAL;
	}

	soc_private =
		(struct cam_ois_soc_private *)o_ctrl->soc_info.soc_private;
	power_info = &soc_private->power_info;

	mutex_lock(&(o_ctrl->ois_mutex));
	switch (cmd->op_code) {
	case CAM_QUERY_CAP:
@@ -764,6 +772,13 @@ int cam_ois_driver_cmd(struct cam_ois_ctrl_t *o_ctrl, void *arg)
		o_ctrl->bridge_intf.link_hdl = -1;
		o_ctrl->bridge_intf.session_hdl = -1;
		o_ctrl->cam_ois_state = CAM_OIS_INIT;

		kfree(power_info->power_setting);
		kfree(power_info->power_down_setting);
		power_info->power_setting = NULL;
		power_info->power_down_setting = NULL;
		power_info->power_down_setting_size = 0;
		power_info->power_setting_size = 0;
		break;
	case CAM_STOP_DEV:
		if (o_ctrl->cam_ois_state != CAM_OIS_START) {
+29 −26
Original line number Diff line number Diff line
@@ -499,8 +499,8 @@ void cam_sensor_shutdown(struct cam_sensor_ctrl_t *s_ctrl)
		&s_ctrl->sensordata->power_info;
	int rc = 0;

	s_ctrl->is_probe_succeed = 0;
	if (s_ctrl->sensor_state == CAM_SENSOR_INIT)
	if ((s_ctrl->sensor_state == CAM_SENSOR_INIT) &&
		(s_ctrl->is_probe_succeed == 0))
		return;

	cam_sensor_release_resource(s_ctrl);
@@ -514,14 +514,15 @@ void cam_sensor_shutdown(struct cam_sensor_ctrl_t *s_ctrl)
	s_ctrl->bridge_intf.device_hdl = -1;
	s_ctrl->bridge_intf.link_hdl = -1;
	s_ctrl->bridge_intf.session_hdl = -1;

	kfree(power_info->power_setting);
	kfree(power_info->power_down_setting);
	power_info->power_setting = NULL;
	power_info->power_down_setting = NULL;

	power_info->power_setting_size = 0;
	power_info->power_down_setting_size = 0;
	s_ctrl->streamon_count = 0;
	s_ctrl->streamoff_count = 0;
	s_ctrl->is_probe_succeed = 0;
	s_ctrl->sensor_state = CAM_SENSOR_INIT;
}

@@ -560,8 +561,6 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
{
	int rc = 0;
	struct cam_control *cmd = (struct cam_control *)arg;
	struct cam_sensor_power_setting *pu = NULL;
	struct cam_sensor_power_setting *pd = NULL;
	struct cam_sensor_power_ctrl_t *power_info =
		&s_ctrl->sensordata->power_info;
	if (!s_ctrl || !arg) {
@@ -591,8 +590,6 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
			rc = cam_handle_mem_ptr(cmd->handle, s_ctrl);
			if (rc < 0) {
				CAM_ERR(CAM_SENSOR, "Get Buffer Handle Failed");
				kfree(pu);
				kfree(pd);
				goto release_mutex;
			}
		} else {
@@ -602,9 +599,6 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
			goto release_mutex;
		}

		pu = power_info->power_setting;
		pd = power_info->power_down_setting;

		/* Parse and fill vreg params for powerup settings */
		rc = msm_camera_fill_vreg_params(
			&s_ctrl->soc_info,
@@ -614,9 +608,7 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
			CAM_ERR(CAM_SENSOR,
				"Fail in filling vreg params for PUP rc %d",
				 rc);
			kfree(pu);
			kfree(pd);
			goto release_mutex;
			goto free_power_settings;
		}

		/* Parse and fill vreg params for powerdown settings*/
@@ -628,18 +620,14 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
			CAM_ERR(CAM_SENSOR,
				"Fail in filling vreg params for PDOWN rc %d",
				 rc);
			kfree(pu);
			kfree(pd);
			goto release_mutex;
			goto free_power_settings;
		}

		/* Power up and probe sensor */
		rc = cam_sensor_power_up(s_ctrl);
		if (rc < 0) {
			CAM_ERR(CAM_SENSOR, "power up failed");
			kfree(pu);
			kfree(pd);
			goto release_mutex;
			goto free_power_settings;
		}

		/* Match sensor ID */
@@ -647,9 +635,7 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
		if (rc < 0) {
			cam_sensor_power_down(s_ctrl);
			msleep(20);
			kfree(pu);
			kfree(pd);
			goto release_mutex;
			goto free_power_settings;
		}

		CAM_INFO(CAM_SENSOR,
@@ -661,9 +647,7 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
		rc = cam_sensor_power_down(s_ctrl);
		if (rc < 0) {
			CAM_ERR(CAM_SENSOR, "fail in Sensor Power Down");
			kfree(pu);
			kfree(pd);
			goto release_mutex;
			goto free_power_settings;
		}
		/*
		 * Set probe succeeded flag to 1 so that no other camera shall
@@ -677,6 +661,15 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
		struct cam_sensor_acquire_dev sensor_acq_dev;
		struct cam_create_dev_hdl bridge_params;

		if ((s_ctrl->is_probe_succeed == 0) ||
			(s_ctrl->sensor_state != CAM_SENSOR_INIT)) {
			CAM_WARN(CAM_SENSOR,
				"Not in right state to aquire %d",
				s_ctrl->sensor_state);
			rc = -EINVAL;
			goto release_mutex;
		}

		if (s_ctrl->bridge_intf.device_hdl != -1) {
			CAM_ERR(CAM_SENSOR, "Device is already acquired");
			rc = -EINVAL;
@@ -885,6 +878,16 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
release_mutex:
	mutex_unlock(&(s_ctrl->cam_sensor_mutex));
	return rc;

free_power_settings:
	kfree(power_info->power_setting);
	kfree(power_info->power_down_setting);
	power_info->power_setting = NULL;
	power_info->power_down_setting = NULL;
	power_info->power_down_setting_size = 0;
	power_info->power_setting_size = 0;
	mutex_unlock(&(s_ctrl->cam_sensor_mutex));
	return rc;
}

int cam_sensor_publish_dev_info(struct cam_req_mgr_device_info *info)
+148 −74
Original line number Diff line number Diff line
@@ -711,8 +711,10 @@ int32_t cam_sensor_update_power_settings(void *cmd_buf,
		kzalloc(sizeof(struct cam_sensor_power_setting) *
			MAX_POWER_CONFIG, GFP_KERNEL);
	if (!power_info->power_down_setting) {
		rc = -ENOMEM;
		goto free_power_settings;
		kfree(power_info->power_setting);
		power_info->power_setting = NULL;
		power_info->power_setting_size = 0;
		return -ENOMEM;
	}

	while (tot_size < cmd_length) {
@@ -722,11 +724,18 @@ int32_t cam_sensor_update_power_settings(void *cmd_buf,
				(struct cam_cmd_power *)ptr;

			power_info->power_setting_size += pwr_cmd->count;
			if (power_info->power_setting_size > MAX_POWER_CONFIG) {
				CAM_ERR(CAM_SENSOR,
					"Invalid: power up setting size %d",
					power_info->power_setting_size);
				rc = -EINVAL;
				goto free_power_settings;
			}
			scr = ptr + sizeof(struct cam_cmd_power);
			tot_size = tot_size + sizeof(struct cam_cmd_power);

			if (pwr_cmd->count == 0)
				CAM_WARN(CAM_SENSOR, "Un expected Command");
				CAM_WARN(CAM_SENSOR, "pwr_up_size is zero");

			for (i = 0; i < pwr_cmd->count; i++, pwr_up++) {
				power_info->power_setting[pwr_up].seq_type =
@@ -746,7 +755,7 @@ int32_t cam_sensor_update_power_settings(void *cmd_buf,
					CAM_ERR(CAM_SENSOR,
						"Error: Cmd Buffer is wrong");
					rc = -EINVAL;
					goto free_power_down_settings;
					goto free_power_settings;
				}
				CAM_DBG(CAM_SENSOR,
				"Seq Type[%d]: %d Config_val: %ld", pwr_up,
@@ -814,9 +823,17 @@ int32_t cam_sensor_update_power_settings(void *cmd_buf,
			scr = ptr + sizeof(struct cam_cmd_power);
			tot_size = tot_size + sizeof(struct cam_cmd_power);
			power_info->power_down_setting_size += pwr_cmd->count;
			if (power_info->power_down_setting_size >
				MAX_POWER_CONFIG) {
				CAM_ERR(CAM_SENSOR,
					"Invalid: power down setting size %d",
					power_info->power_down_setting_size);
				rc = -EINVAL;
				goto free_power_settings;
			}

			if (pwr_cmd->count == 0)
				CAM_ERR(CAM_SENSOR, "Invalid Command");
				CAM_ERR(CAM_SENSOR, "pwr_down size is zero");

			for (i = 0; i < pwr_cmd->count; i++, pwr_down++) {
				pwr_settings =
@@ -840,7 +857,7 @@ int32_t cam_sensor_update_power_settings(void *cmd_buf,
					CAM_ERR(CAM_SENSOR,
						"Command Buffer is wrong");
					rc = -EINVAL;
					goto free_power_down_settings;
					goto free_power_settings;
				}
				CAM_DBG(CAM_SENSOR,
					"Seq Type[%d]: %d Config_val: %ld",
@@ -854,16 +871,19 @@ int32_t cam_sensor_update_power_settings(void *cmd_buf,
			CAM_ERR(CAM_SENSOR,
				"Error: Un expected Header Type: %d",
				cmm_hdr->cmd_type);
			rc = -EINVAL;
			goto free_power_settings;
		}
	}

	return rc;
free_power_down_settings:
	kfree(power_info->power_down_setting);
	power_info->power_down_setting = NULL;
free_power_settings:
	kfree(power_info->power_down_setting);
	kfree(power_info->power_setting);
	power_info->power_down_setting = NULL;
	power_info->power_setting = NULL;
	power_info->power_down_setting_size = 0;
	power_info->power_setting_size = 0;
	return rc;
}

@@ -1262,10 +1282,62 @@ int msm_cam_sensor_handle_reg_gpio(int seq_type,
	return 0;
}

static int cam_config_mclk_reg(struct cam_sensor_power_ctrl_t *ctrl,
	struct cam_hw_soc_info *soc_info, int32_t index)
{
	int32_t num_vreg = 0, j = 0, rc = 0, idx = 0;
	struct cam_sensor_power_setting *ps = NULL;
	struct cam_sensor_power_setting *pd = NULL;

	num_vreg = soc_info->num_rgltr;

	pd = &ctrl->power_down_setting[index];

	for (j = 0; j < num_vreg; j++) {
		if (!strcmp(soc_info->rgltr_name[j], "cam_clk")) {
			ps = NULL;
			for (idx = 0; idx < ctrl->power_setting_size; idx++) {
				if (ctrl->power_setting[idx].seq_type ==
					pd->seq_type) {
					ps = &ctrl->power_setting[idx];
					break;
				}
			}

			if (ps != NULL) {
				CAM_DBG(CAM_SENSOR, "Disable MCLK Regulator");
				rc = cam_soc_util_regulator_disable(
					soc_info->rgltr[j],
					soc_info->rgltr_name[j],
					soc_info->rgltr_min_volt[j],
					soc_info->rgltr_max_volt[j],
					soc_info->rgltr_op_mode[j],
					soc_info->rgltr_delay[j]);

				if (rc) {
					CAM_ERR(CAM_SENSOR,
						"MCLK REG DISALBE FAILED: %d",
						rc);
					return rc;
				}

				ps->data[0] =
					soc_info->rgltr[j];

				regulator_put(
					soc_info->rgltr[j]);
				soc_info->rgltr[j] = NULL;
			}
		}
	}

	return rc;
}

int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
		struct cam_hw_soc_info *soc_info)
{
	int rc = 0, index = 0, no_gpio = 0, ret = 0, num_vreg, j = 0;
	int rc = 0, index = 0, no_gpio = 0, ret = 0, num_vreg, j = 0, i = 0;
	int32_t vreg_idx = -1;
	struct cam_sensor_power_setting *power_setting = NULL;
	struct msm_camera_gpio_num_info *gpio_num_info = NULL;
@@ -1362,6 +1434,7 @@ int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
							soc_info->rgltr_name[j],
							rc);
						soc_info->rgltr[j] = NULL;
						goto power_up_failed;
					}

					rc =  cam_soc_util_regulator_enable(
@@ -1371,7 +1444,11 @@ int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
					soc_info->rgltr_max_volt[j],
					soc_info->rgltr_op_mode[j],
					soc_info->rgltr_delay[j]);

					if (rc) {
						CAM_ERR(CAM_SENSOR,
							"Reg enable failed");
						goto power_up_failed;
					}
					power_setting->data[0] =
						soc_info->rgltr[j];
				}
@@ -1452,6 +1529,7 @@ int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
						rc);

					soc_info->rgltr[vreg_idx] = NULL;
					goto power_up_failed;
				}

				rc =  cam_soc_util_regulator_enable(
@@ -1461,7 +1539,12 @@ int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
					soc_info->rgltr_max_volt[vreg_idx],
					soc_info->rgltr_op_mode[vreg_idx],
					soc_info->rgltr_delay[vreg_idx]);

				if (rc) {
					CAM_ERR(CAM_SENSOR,
						"Reg Enable failed for %s",
						soc_info->rgltr_name[vreg_idx]);
					goto power_up_failed;
				}
				power_setting->data[0] =
						soc_info->rgltr[vreg_idx];
			} else {
@@ -1504,6 +1587,18 @@ int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
		CAM_DBG(CAM_SENSOR, "type %d",
			power_setting->seq_type);
		switch (power_setting->seq_type) {
		case SENSOR_MCLK:
			for (i = soc_info->num_clk - 1; i >= 0; i--) {
				cam_soc_util_clk_disable(soc_info->clk[i],
					soc_info->clk_name[i]);
			}
			ret = cam_config_mclk_reg(ctrl, soc_info, index);
			if (ret < 0) {
				CAM_ERR(CAM_SENSOR,
					"config clk reg failed rc: %d", ret);
				continue;
			}
			break;
		case SENSOR_RESET:
		case SENSOR_STANDBY:
		case SENSOR_CUSTOM_GPIO1:
@@ -1536,11 +1631,21 @@ int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
					soc_info->rgltr_op_mode[vreg_idx],
					soc_info->rgltr_delay[vreg_idx]);

				if (rc) {
					CAM_ERR(CAM_SENSOR,
					"Fail to disalbe reg: %s",
					soc_info->rgltr_name[vreg_idx]);
					soc_info->rgltr[vreg_idx] = NULL;
					msm_cam_sensor_handle_reg_gpio(
						power_setting->seq_type,
						gpio_num_info,
						GPIOF_OUT_INIT_LOW);
					continue;
				}
				power_setting->data[0] =
						soc_info->rgltr[vreg_idx];

				regulator_put(
					soc_info->rgltr[vreg_idx]);
				regulator_put(soc_info->rgltr[vreg_idx]);
				soc_info->rgltr[vreg_idx] = NULL;
			} else {
				CAM_ERR(CAM_SENSOR, "seq_val:%d > num_vreg: %d",
@@ -1606,54 +1711,6 @@ msm_camera_get_power_settings(struct cam_sensor_power_ctrl_t *ctrl,
	return ps;
}

static int cam_config_mclk_reg(struct cam_sensor_power_ctrl_t *ctrl,
	struct cam_hw_soc_info *soc_info, int32_t index)
{
	int32_t num_vreg = 0, j = 0, rc = 0, idx = 0;
	struct cam_sensor_power_setting *ps = NULL;
	struct cam_sensor_power_setting *pd = NULL;

	num_vreg = soc_info->num_rgltr;

	pd = &ctrl->power_down_setting[index];

	for (j = 0; j < num_vreg; j++) {
		if (!strcmp(soc_info->rgltr_name[j], "cam_clk")) {

			ps = NULL;
			for (idx = 0; idx <
				ctrl->power_setting_size; idx++) {
				if (ctrl->power_setting[idx].seq_type
					== pd->seq_type) {
					ps = &ctrl->power_setting[idx];
					break;
				}
			}

			if (ps != NULL) {
				CAM_DBG(CAM_SENSOR, "Disable Regulator");

				rc = cam_soc_util_regulator_disable(
					soc_info->rgltr[j],
					soc_info->rgltr_name[j],
					soc_info->rgltr_min_volt[j],
					soc_info->rgltr_max_volt[j],
					soc_info->rgltr_op_mode[j],
					soc_info->rgltr_delay[j]);

				ps->data[0] =
					soc_info->rgltr[j];

				regulator_put(
					soc_info->rgltr[j]);
				soc_info->rgltr[j] = NULL;
			}
		}
	}

	return rc;
}

int msm_camera_power_down(struct cam_sensor_power_ctrl_t *ctrl,
		struct cam_hw_soc_info *soc_info)
{
@@ -1676,8 +1733,14 @@ int msm_camera_power_down(struct cam_sensor_power_ctrl_t *ctrl,
		return -EINVAL;
	}

	if (ctrl->power_down_setting_size > MAX_POWER_CONFIG) {
		CAM_ERR(CAM_SENSOR, "Invalid: power setting size %d",
			ctrl->power_setting_size);
		return -EINVAL;
	}

	for (index = 0; index < ctrl->power_down_setting_size; index++) {
		CAM_DBG(CAM_SENSOR, "index %d",  index);
		CAM_DBG(CAM_SENSOR, "power_down_index %d",  index);
		pd = &ctrl->power_down_setting[index];
		if (!pd) {
			CAM_ERR(CAM_SENSOR,
@@ -1687,21 +1750,20 @@ int msm_camera_power_down(struct cam_sensor_power_ctrl_t *ctrl,
		}

		ps = NULL;
		CAM_DBG(CAM_SENSOR, "type %d",  pd->seq_type);
		CAM_DBG(CAM_SENSOR, "seq_type %d",  pd->seq_type);
		switch (pd->seq_type) {
		case SENSOR_MCLK:
			ret = cam_config_mclk_reg(ctrl, soc_info, index);
			if (ret < 0) {
				CAM_ERR(CAM_SENSOR,
					"config clk reg failed rc: %d", ret);
				return ret;
			}
			//cam_soc_util_clk_disable_default(soc_info);
			for (i = soc_info->num_clk - 1; i >= 0; i--) {
				cam_soc_util_clk_disable(soc_info->clk[i],
					soc_info->clk_name[i]);
			}

			ret = cam_config_mclk_reg(ctrl, soc_info, index);
			if (ret < 0) {
				CAM_ERR(CAM_SENSOR,
					"config clk reg failed rc: %d", ret);
				continue;
			}
			break;
		case SENSOR_RESET:
		case SENSOR_STANDBY:
@@ -1741,7 +1803,19 @@ int msm_camera_power_down(struct cam_sensor_power_ctrl_t *ctrl,
					soc_info->rgltr_max_volt[ps->seq_val],
					soc_info->rgltr_op_mode[ps->seq_val],
					soc_info->rgltr_delay[ps->seq_val]);

					if (ret) {
						CAM_ERR(CAM_SENSOR,
						"Reg: %s disable failed",
						soc_info->rgltr_name[
							ps->seq_val]);
						soc_info->rgltr[ps->seq_val] =
							NULL;
						msm_cam_sensor_handle_reg_gpio(
							pd->seq_type,
							gpio_num_info,
							GPIOF_OUT_INIT_LOW);
						continue;
					}
					ps->data[0] =
						soc_info->rgltr[ps->seq_val];
					regulator_put(