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

Commit 6b7576b8 authored by Depeng Shao's avatar Depeng Shao
Browse files

msm: camera: Fix some shared gpio issues



Do not override the soc private structure, it will
cause kernel panic. Update the ref count logic to
just power on, power down one time. Also, free the
power setting in sensor sub module.

Change-Id: Ife891d393c4c665eca05cff6ea01e64608c14d97
Signed-off-by: default avatarDepeng Shao <depengs@codeaurora.org>
parent 6e4bc937
Loading
Loading
Loading
Loading
+23 −9
Original line number Diff line number Diff line
@@ -186,13 +186,6 @@ static int32_t cam_actuator_driver_i2c_probe(struct i2c_client *client,
		goto free_ctrl;
	}

	soc_private = (struct cam_actuator_soc_private *)(id->driver_data);
	if (!soc_private) {
		CAM_ERR(CAM_EEPROM, "board info NULL");
		rc = -EINVAL;
		goto free_ctrl;
	}

	rc = cam_actuator_init_subdev(a_ctrl);
	if (rc)
		goto free_soc;
@@ -249,8 +242,10 @@ static int32_t cam_actuator_driver_i2c_probe(struct i2c_client *client,

static int32_t cam_actuator_platform_remove(struct platform_device *pdev)
{
	struct cam_actuator_ctrl_t  *a_ctrl;
	int32_t rc = 0;
	struct cam_actuator_ctrl_t      *a_ctrl;
	struct cam_actuator_soc_private *soc_private;
	struct cam_sensor_power_ctrl_t  *power_info;

	a_ctrl = platform_get_drvdata(pdev);
	if (!a_ctrl) {
@@ -258,8 +253,15 @@ static int32_t cam_actuator_platform_remove(struct platform_device *pdev)
		return 0;
	}

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

	kfree(a_ctrl->io_master_info.cci_client);
	a_ctrl->io_master_info.cci_client = NULL;
	kfree(power_info->power_setting);
	kfree(power_info->power_down_setting);
	kfree(a_ctrl->soc_info.soc_private);
	kfree(a_ctrl->i2c_data.per_frame);
	a_ctrl->i2c_data.per_frame = NULL;
	devm_kfree(&pdev->dev, a_ctrl);
@@ -269,17 +271,29 @@ static int32_t cam_actuator_platform_remove(struct platform_device *pdev)

static int32_t cam_actuator_driver_i2c_remove(struct i2c_client *client)
{
	struct cam_actuator_ctrl_t  *a_ctrl = i2c_get_clientdata(client);
	int32_t rc = 0;
	struct cam_actuator_ctrl_t      *a_ctrl =
		i2c_get_clientdata(client);
	struct cam_actuator_soc_private *soc_private;
	struct cam_sensor_power_ctrl_t  *power_info;

	/* Handle I2C Devices */
	if (!a_ctrl) {
		CAM_ERR(CAM_ACTUATOR, "Actuator device is NULL");
		return -EINVAL;
	}

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

	/*Free Allocated Mem */
	kfree(a_ctrl->i2c_data.per_frame);
	a_ctrl->i2c_data.per_frame = NULL;
	kfree(power_info->power_setting);
	kfree(power_info->power_down_setting);
	kfree(a_ctrl->soc_info.soc_private);
	a_ctrl->soc_info.soc_private = NULL;
	kfree(a_ctrl);
	return rc;
}
+11 −2
Original line number Diff line number Diff line
@@ -657,6 +657,7 @@ static int32_t cam_eeprom_pkt_parse(struct cam_eeprom_ctrl_t *e_ctrl, void *arg)
	struct cam_packet              *csl_packet = NULL;
	struct cam_eeprom_soc_private  *soc_private =
		(struct cam_eeprom_soc_private *)e_ctrl->soc_info.soc_private;
	struct cam_sensor_power_ctrl_t *power_info = &soc_private->power_info;

	ioctl_ctrl = (struct cam_control *)arg;

@@ -750,16 +751,21 @@ static int32_t cam_eeprom_pkt_parse(struct cam_eeprom_ctrl_t *e_ctrl, void *arg)
memdata_free:
	kfree(e_ctrl->cal_data.mapdata);
error:
	kfree(power_info->power_setting);
	kfree(power_info->power_down_setting);
	kfree(e_ctrl->cal_data.map);
	e_ctrl->cal_data.num_data = 0;
	e_ctrl->cal_data.num_map = 0;
	e_ctrl->cam_eeprom_state = CAM_EEPROM_ACQUIRE;
	e_ctrl->cam_eeprom_state = CAM_EEPROM_INIT;
	return rc;
}

void cam_eeprom_shutdown(struct cam_eeprom_ctrl_t *e_ctrl)
{
	int rc;
	struct cam_eeprom_soc_private  *soc_private =
		(struct cam_eeprom_soc_private *)e_ctrl->soc_info.soc_private;
	struct cam_sensor_power_ctrl_t *power_info = &soc_private->power_info;

	if (e_ctrl->cam_eeprom_state == CAM_EEPROM_INIT)
		return;
@@ -779,6 +785,9 @@ void cam_eeprom_shutdown(struct cam_eeprom_ctrl_t *e_ctrl)
		e_ctrl->bridge_intf.device_hdl = -1;
		e_ctrl->bridge_intf.link_hdl = -1;
		e_ctrl->bridge_intf.session_hdl = -1;

		kfree(power_info->power_setting);
		kfree(power_info->power_down_setting);
	}

	e_ctrl->cam_eeprom_state = CAM_EEPROM_INIT;
+5 −10
Original line number Diff line number Diff line
@@ -201,13 +201,6 @@ static int cam_eeprom_i2c_driver_probe(struct i2c_client *client,
		goto free_soc;
	}

	soc_private = (struct cam_eeprom_soc_private *)(id->driver_data);
	if (!soc_private) {
		CAM_ERR(CAM_EEPROM, "board info NULL");
		rc = -EINVAL;
		goto ectrl_free;
	}

	rc = cam_eeprom_init_subdev(e_ctrl);
	if (rc)
		goto free_soc;
@@ -260,10 +253,9 @@ static int cam_eeprom_i2c_driver_remove(struct i2c_client *client)
		return -EINVAL;
	}

	if (soc_private) {
		kfree(soc_private->power_info.gpio_num_info);
	if (soc_private)
		kfree(soc_private);
	}

	kfree(e_ctrl);

	return 0;
@@ -451,6 +443,9 @@ static int32_t cam_eeprom_platform_driver_probe(

	platform_set_drvdata(pdev, e_ctrl);
	v4l2_set_subdevdata(&e_ctrl->v4l2_dev_str.sd, e_ctrl);

	e_ctrl->cam_eeprom_state = CAM_EEPROM_INIT;

	return rc;
free_soc:
	kfree(soc_private);
+20 −2
Original line number Diff line number Diff line
@@ -227,12 +227,20 @@ static int cam_ois_i2c_driver_probe(struct i2c_client *client,
static int cam_ois_i2c_driver_remove(struct i2c_client *client)
{
	struct cam_ois_ctrl_t          *o_ctrl = i2c_get_clientdata(client);
	struct cam_ois_soc_private     *soc_private;
	struct cam_sensor_power_ctrl_t *power_info;

	if (!o_ctrl) {
		CAM_ERR(CAM_OIS, "ois device is NULL");
		return -EINVAL;
	}

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

	kfree(power_info->power_setting);
	kfree(power_info->power_down_setting);
	kfree(o_ctrl->soc_info.soc_private);
	kfree(o_ctrl);

@@ -302,6 +310,8 @@ static int32_t cam_ois_platform_driver_probe(
	platform_set_drvdata(pdev, o_ctrl);
	v4l2_set_subdevdata(&o_ctrl->v4l2_dev_str.sd, o_ctrl);

	o_ctrl->cam_ois_state = CAM_OIS_INIT;

	return rc;
unreg_subdev:
	cam_unregister_subdev(&(o_ctrl->v4l2_dev_str));
@@ -317,6 +327,8 @@ static int32_t cam_ois_platform_driver_probe(
static int cam_ois_platform_driver_remove(struct platform_device *pdev)
{
	struct cam_ois_ctrl_t          *o_ctrl;
	struct cam_ois_soc_private     *soc_private;
	struct cam_sensor_power_ctrl_t *power_info;

	o_ctrl = platform_get_drvdata(pdev);
	if (!o_ctrl) {
@@ -324,6 +336,12 @@ static int cam_ois_platform_driver_remove(struct platform_device *pdev)
		return -EINVAL;
	}

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

	kfree(power_info->power_setting);
	kfree(power_info->power_down_setting);
	kfree(o_ctrl->soc_info.soc_private);
	kfree(o_ctrl->io_master_info.cci_client);
	kfree(o_ctrl);
+12 −8
Original line number Diff line number Diff line
@@ -555,16 +555,20 @@ int cam_res_mgr_gpio_set_value(unsigned int gpio, int value)
	if (!found) {
		gpio_set_value_cansleep(gpio, value);
	} else {
		if (value)
		if (value) {
			gpio_res->power_on_count++;
		else
			gpio_res->power_on_count--;

		if (gpio_res->power_on_count > 0) {
			if (gpio_res->power_on_count < 2) {
				gpio_set_value_cansleep(gpio, value);
				CAM_DBG(CAM_RES,
					"Shared GPIO(%d) : HIGH", gpio);
			}
		} else {
			gpio_res->power_on_count = 0;
			gpio_set_value_cansleep(gpio, 0);
			gpio_res->power_on_count--;
			if (gpio_res->power_on_count < 1) {
				gpio_set_value_cansleep(gpio, value);
				CAM_DBG(CAM_RES,
					"Shared GPIO(%d) : LOW", gpio);
			}
		}
	}