BACKPORT: msm: camera: Add regulator enable and disable independent of CSID

Regulator enable and disable of CSIPHY depends on the CSID module.
Make the enable and disable of clk regulator independent of CSIPHY.

Bug: 33299365
CRs-Fixed: 1107702
Change-Id: Iabb5eb28d63b34a4c3201c53be17054a1907f4fe
Signed-off-by: Ravi Kishore Tanuku <rktanuku@codeaurora.org>
Signed-off-by: VijayaKumar T M <vtmuni@codeaurora.org>
Signed-off-by: Dennis Cagle <d-cagle@codeaurora.org>
(cherry picked from commit b1bb44c9cca61e48ec6158abad6e7969a8e58abf)
CVE-2017-8264
Signed-off-by: Kevin F. Haggerty <haggertk@lineageos.org>
This commit is contained in:
Nick Desaulniers 2017-05-10 11:39:45 -07:00 committed by Francescodario Cuzzocrea
parent 375d3f2b86
commit 62856dafc3
3 changed files with 99 additions and 1 deletions

View File

@ -31,6 +31,8 @@
reg-names = "csiphy", "csiphy_clk_mux";
interrupts = <0 78 0>;
interrupt-names = "csiphy";
qcom,csi-vdd-voltage = <1800000>;
qcom,mipi-csi-vdd-supply = <&pma8084_l12>;
};
qcom,csiphy@fda0b000 {
@ -41,6 +43,8 @@
reg-names = "csiphy", "csiphy_clk_mux";
interrupts = <0 79 0>;
interrupt-names = "csiphy";
qcom,csi-vdd-voltage = <1800000>;
qcom,mipi-csi-vdd-supply = <&pma8084_l12>;
};
qcom,csiphy@fda0b400 {
@ -51,6 +55,8 @@
reg-names = "csiphy", "csiphy_clk_mux";
interrupts = <0 80 0>;
interrupt-names = "csiphy";
qcom,csi-vdd-voltage = <1800000>;
qcom,mipi-csi-vdd-supply = <&pma8084_l12>;
};
qcom,csid@fda08000 {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2014, 2017 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -27,6 +27,10 @@
#define CSIPHY_VERSION_V3 0x10
#define MSM_CSIPHY_DRV_NAME "msm_csiphy"
static struct camera_vreg_t csiphy_vreg_info[] = {
{"qcom,mipi-csi-vdd", 0, 0, 12000},
};
#undef CDBG
#ifdef CONFIG_MSMB_CAMERA_DEBUG
#define CDBG(fmt, args...) pr_err(fmt, ##args)
@ -222,6 +226,21 @@ static int msm_csiphy_init(struct csiphy_device *csiphy_dev)
}
CDBG("%s:%d called\n", __func__, __LINE__);
rc = msm_camera_config_vreg(&csiphy_dev->pdev->dev,
csiphy_vreg_info, ARRAY_SIZE(csiphy_vreg_info),
NULL, 0, &csiphy_dev->csi_vdd, 1);
if (rc < 0) {
pr_err("%s: regulator config failed\n", __func__);
goto csiphy_vreg_config_fail;
}
rc = msm_camera_enable_vreg(&csiphy_dev->pdev->dev,
csiphy_vreg_info, ARRAY_SIZE(csiphy_vreg_info),
NULL, 0, &csiphy_dev->csi_vdd, 1);
if (rc < 0) {
pr_err("%s: regulator enable failed\n", __func__);
goto csiphy_vreg_enable_fail;
}
if (CSIPHY_VERSION < CSIPHY_VERSION_V3) {
CDBG("%s:%d called\n", __func__, __LINE__);
rc = msm_cam_clk_enable(&csiphy_dev->pdev->dev,
@ -272,6 +291,16 @@ static int msm_csiphy_init(struct csiphy_device *csiphy_dev)
csiphy_dev->hw_version);
csiphy_dev->csiphy_state = CSIPHY_POWER_UP;
return 0;
csiphy_vreg_enable_fail:
rc = msm_camera_config_vreg(&csiphy_dev->pdev->dev,
csiphy_vreg_info, ARRAY_SIZE(csiphy_vreg_info),
NULL, 0, &csiphy_dev->csi_vdd, 0);
csiphy_vreg_config_fail:
iounmap(csiphy_dev->base);
csiphy_dev->base = NULL;
return rc;
}
#else
static int msm_csiphy_init(struct csiphy_device *csiphy_dev)
@ -309,6 +338,20 @@ static int msm_csiphy_init(struct csiphy_device *csiphy_dev)
}
CDBG("%s:%d called\n", __func__, __LINE__);
rc = msm_camera_config_vreg(&csiphy_dev->pdev->dev,
csiphy_vreg_info, ARRAY_SIZE(csiphy_vreg_info),
NULL, 0, &csiphy_dev->csi_vdd, 1);
if (rc < 0) {
pr_err("%s: regulator config failed\n", __func__);
goto csiphy_vreg_config_fail;
}
rc = msm_camera_enable_vreg(&csiphy_dev->pdev->dev,
csiphy_vreg_info, ARRAY_SIZE(csiphy_vreg_info),
NULL, 0, &csiphy_dev->csi_vdd, 1);
if (rc < 0) {
pr_err("%s: regulator enable failed\n", __func__);
goto csiphy_vreg_enable_fail;
}
if (CSIPHY_VERSION < CSIPHY_VERSION_V3) {
CDBG("%s:%d called\n", __func__, __LINE__);
@ -360,6 +403,15 @@ static int msm_csiphy_init(struct csiphy_device *csiphy_dev)
csiphy_dev->hw_version);
csiphy_dev->csiphy_state = CSIPHY_POWER_UP;
return 0;
csiphy_vreg_enable_fail:
rc = msm_camera_config_vreg(&csiphy_dev->pdev->dev,
csiphy_vreg_info, ARRAY_SIZE(csiphy_vreg_info),
NULL, 0, &csiphy_dev->csi_vdd, 0);
csiphy_vreg_config_fail:
iounmap(csiphy_dev->base);
csiphy_dev->base = NULL;
return rc;
}
#endif
@ -435,6 +487,18 @@ static int msm_csiphy_release(struct csiphy_device *csiphy_dev, void *arg)
iounmap(csiphy_dev->clk_mux_base);
}
msm_camera_enable_vreg(&csiphy_dev->pdev->dev,
csiphy_vreg_info, ARRAY_SIZE(csiphy_vreg_info),
NULL, 0, &csiphy_dev->csi_vdd, 0);
msm_camera_config_vreg(&csiphy_dev->pdev->dev,
csiphy_vreg_info, ARRAY_SIZE(csiphy_vreg_info),
NULL, 0, &csiphy_dev->csi_vdd, 0);
if (!IS_ERR_OR_NULL(csiphy_dev->reg_ptr)) {
regulator_disable(csiphy_dev->reg_ptr);
regulator_put(csiphy_dev->reg_ptr);
}
iounmap(csiphy_dev->base);
csiphy_dev->base = NULL;
csiphy_dev->csiphy_state = CSIPHY_POWER_DOWN;
@ -504,6 +568,18 @@ static int msm_csiphy_release(struct csiphy_device *csiphy_dev, void *arg)
iounmap(csiphy_dev->clk_mux_base);
}
msm_camera_enable_vreg(&csiphy_dev->pdev->dev,
csiphy_vreg_info, ARRAY_SIZE(csiphy_vreg_info),
NULL, 0, &csiphy_dev->csi_vdd, 0);
msm_camera_config_vreg(&csiphy_dev->pdev->dev,
csiphy_vreg_info, ARRAY_SIZE(csiphy_vreg_info),
NULL, 0, &csiphy_dev->csi_vdd, 0);
if (!IS_ERR_OR_NULL(csiphy_dev->reg_ptr)) {
regulator_disable(csiphy_dev->reg_ptr);
regulator_put(csiphy_dev->reg_ptr);
}
iounmap(csiphy_dev->base);
csiphy_dev->base = NULL;
csiphy_dev->csiphy_state = CSIPHY_POWER_DOWN;
@ -607,6 +683,7 @@ static const struct v4l2_subdev_ops msm_csiphy_subdev_ops = {
static int __devinit csiphy_probe(struct platform_device *pdev)
{
struct csiphy_device *new_csiphy_dev;
uint32_t csi_vdd_voltage = 0;
int rc = 0;
new_csiphy_dev = kzalloc(sizeof(struct csiphy_device), GFP_KERNEL);
@ -626,6 +703,19 @@ static int __devinit csiphy_probe(struct platform_device *pdev)
"cell-index", &pdev->id);
pr_err("%s: device id = %d\n", __func__, pdev->id);
rc = of_property_read_u32((&pdev->dev)->of_node,
"qcom,csi-vdd-voltage", &csi_vdd_voltage);
if (rc < 0) {
pr_err("%s:%d failed to read qcom,csi-vdd-voltage\n",
__func__, __LINE__);
return rc;
}
CDBG("%s:%d reading mipi_csi_vdd is %d\n", __func__, __LINE__,
csi_vdd_voltage);
csiphy_vreg_info[0].min_voltage = csi_vdd_voltage;
csiphy_vreg_info[0].max_voltage = csi_vdd_voltage;
new_csiphy_dev->mem = platform_get_resource_byname(pdev,
IORESOURCE_MEM, "csiphy");
if (!new_csiphy_dev->mem) {

View File

@ -45,6 +45,8 @@ struct csiphy_device {
struct clk *csiphy_clk[4];
uint8_t ref_count;
uint16_t lane_mask[MAX_CSIPHY];
struct regulator *csi_vdd;
struct regulator *reg_ptr;
};
#define VIDIOC_MSM_CSIPHY_RELEASE \