diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2016-09-20 10:20:45 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-09-20 10:20:44 -0700 |
commit | 9e2d528dc47d04e98c5e6f1c4ef84fc268115d36 (patch) | |
tree | f394a5de94a0b24d0ffbd5e1c43bce7eee94ad21 | |
parent | bfbc8a0ddad9c43c26d94ad86a7d3cdc64ee762c (diff) | |
parent | 48c55694f1ea57edab958c5d95bde3e45e9a66aa (diff) |
Merge "msm: camera: Add support for reset controller framework"
8 files changed, 70 insertions, 16 deletions
diff --git a/Documentation/devicetree/bindings/media/video/msm-cpp.txt b/Documentation/devicetree/bindings/media/video/msm-cpp.txt index b39c20ecbf22..52abf409cb65 100644 --- a/Documentation/devicetree/bindings/media/video/msm-cpp.txt +++ b/Documentation/devicetree/bindings/media/video/msm-cpp.txt @@ -22,6 +22,10 @@ Required properties: case dynamic clock scaling based on prevalent streams need lower clock rate. - qcom,cpp-fw-payload-info: Child node for cpp node having infomration on cpp firmware payload offsets. This is mandatory node. +- resets: reset specifier pair consists of phandle for the reset controller + and reset lines used by this controller. +- reset-names: reset signal name strings sorted in the same order as the resets + property. Required properties of the child node: - qcom,stripe-base = Base offset of stripes in cpp payload. @@ -120,6 +124,7 @@ Example: qcom,ref-we-mmu-pf-ptr-off = <22>; qcom,set-group-buffer-len = <135>; qcom,dup-frame-indicator-off = <70>; - + resets = <&clock_mmss MMSS_CAMSS_MICRO_BCR>; + reset-names = "micro_iface_reset"; }; }; diff --git a/arch/arm/boot/dts/qcom/msm8996-camera.dtsi b/arch/arm/boot/dts/qcom/msm8996-camera.dtsi index 3422e5e7f500..282e6bcb713b 100644 --- a/arch/arm/boot/dts/qcom/msm8996-camera.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996-camera.dtsi @@ -623,6 +623,10 @@ "camss_cpp_axi_clk", "camss_cpp_clk", "micro_iface_clk", "camss_ahb_clk", "smmu_cpp_axi_clk", "cpp_vbif_ahb_clk"; + + resets = <&clock_mmss CAMSS_MICRO_BCR>; + reset-names = "micro_iface_reset"; + qcom,clock-rates = <0 0 0 480000000 0 0 480000000 0 0 0 0>; qcom,min-clock-rate = <200000000>; qcom,bus-master = <1>; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-camera.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-camera.dtsi index b4516f381c0c..154bc5b092df 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-camera.dtsi +++ b/arch/arm/boot/dts/qcom/msmcobalt-camera.dtsi @@ -405,6 +405,8 @@ <106 512 0 0>, <106 512 0 0>; qcom,msm-bus-vector-dyn-vote; + resets = <&clock_mmss CAMSS_MICRO_BCR>; + reset-names = "micro_iface_reset"; qcom,cpp-fw-payload-info { qcom,stripe-base = <790>; qcom,plane-base = <715>; diff --git a/drivers/media/platform/msm/camera_v2/common/cam_soc_api.c b/drivers/media/platform/msm/camera_v2/common/cam_soc_api.c index 8da079d9d0c8..d6bb18522e0c 100644 --- a/drivers/media/platform/msm/camera_v2/common/cam_soc_api.c +++ b/drivers/media/platform/msm/camera_v2/common/cam_soc_api.c @@ -542,6 +542,28 @@ int msm_camera_put_clk_info_and_rates(struct platform_device *pdev, } EXPORT_SYMBOL(msm_camera_put_clk_info_and_rates); +/* Get reset info from DT */ +int msm_camera_get_reset_info(struct platform_device *pdev, + struct reset_control **micro_iface_reset) +{ + if (!pdev || !micro_iface_reset) + return -EINVAL; + + if (of_property_match_string(pdev->dev.of_node, "reset-names", + "micro_iface_reset")) { + pr_err("err: Reset property not found\n"); + return -EINVAL; + } + + *micro_iface_reset = devm_reset_control_get + (&pdev->dev, "micro_iface_reset"); + if (IS_ERR(*micro_iface_reset)) + return PTR_ERR(*micro_iface_reset); + + return 0; +} +EXPORT_SYMBOL(msm_camera_get_reset_info); + /* Get regulators from DT */ int msm_camera_get_regulator_info(struct platform_device *pdev, struct msm_cam_regulator **vdd_info, diff --git a/drivers/media/platform/msm/camera_v2/common/cam_soc_api.h b/drivers/media/platform/msm/camera_v2/common/cam_soc_api.h index b4494d4d6bab..0e9d26bebe30 100644 --- a/drivers/media/platform/msm/camera_v2/common/cam_soc_api.h +++ b/drivers/media/platform/msm/camera_v2/common/cam_soc_api.h @@ -21,6 +21,7 @@ #include <linux/regulator/consumer.h> #include <linux/interrupt.h> #include <linux/slab.h> +#include <linux/reset.h> #include <soc/qcom/camera2.h> enum cam_bus_client { @@ -187,6 +188,21 @@ int msm_camera_clk_enable(struct device *dev, long msm_camera_clk_set_rate(struct device *dev, struct clk *clk, long clk_rate); + +/** + * @brief : Gets reset info + * + * This function extracts the reset information for a specific + * platform device + * + * @param pdev : platform device to get reset information + * @param micro_iface_reset : Pointer to populate the reset names + * + * @return Status of operation. Negative in case of error. Zero otherwise. + */ + +int msm_camera_get_reset_info(struct platform_device *pdev, + struct reset_control **micro_iface_reset); /** * @brief : Sets flags of a clock * diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c index f4add41c85c9..3ac4c3af3208 100644 --- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c +++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c @@ -4017,11 +4017,20 @@ static int cpp_probe(struct platform_device *pdev) } } + rc = msm_camera_get_reset_info(pdev, + &cpp_dev->micro_iface_reset); + if (rc < 0) { + cpp_dev->micro_iface_reset = NULL; + pr_err("%s: failed to get micro_iface_reset\n", + __func__); + goto get_reg_err; + } + rc = msm_camera_get_regulator_info(pdev, &cpp_dev->cpp_vdd, &cpp_dev->num_reg); if (rc < 0) { pr_err("%s: failed to get the regulators\n", __func__); - goto get_reg_err; + goto get_reset_err; } msm_cpp_fetch_dt_params(cpp_dev); @@ -4104,6 +4113,8 @@ static int cpp_probe(struct platform_device *pdev) cpp_probe_init_error: media_entity_cleanup(&cpp_dev->msm_sd.sd.entity); msm_sd_unregister(&cpp_dev->msm_sd); +get_reset_err: + reset_control_put(cpp_dev->micro_iface_reset); get_reg_err: msm_camera_put_clk_info(pdev, &cpp_dev->clk_info, &cpp_dev->cpp_clk, cpp_dev->num_clks); @@ -4161,6 +4172,9 @@ static int cpp_device_remove(struct platform_device *dev) msm_camera_unregister_bus_client(CAM_BUS_CLIENT_CPP); mutex_destroy(&cpp_dev->mutex); kfree(cpp_dev->work); + + reset_control_put(cpp_dev->micro_iface_reset); + destroy_workqueue(cpp_dev->timer_wq); kfree(cpp_dev->cpp_clk); kfree(cpp_dev); diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h index 1784e27b1e37..d5abe0202717 100644 --- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h +++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h @@ -211,6 +211,7 @@ struct cpp_device { struct clk **cpp_clk; struct msm_cam_clk_info *clk_info; size_t num_clks; + struct reset_control *micro_iface_reset; struct msm_cam_regulator *cpp_vdd; int num_reg; struct mutex mutex; diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c index ee52284e3ae3..2c313016bc90 100644 --- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c +++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c @@ -103,20 +103,11 @@ static int cpp_get_clk_freq_tbl(struct clk *clk, struct cpp_hw_info *hw_info, int msm_cpp_set_micro_clk(struct cpp_device *cpp_dev) { - uint32_t msm_micro_iface_idx; int rc; - msm_micro_iface_idx = msm_cpp_get_clock_index(cpp_dev, - "micro_iface_clk"); - if (msm_micro_iface_idx < 0) { - pr_err("Fail to get clock index\n"); - return -EINVAL; - } - - rc = clk_reset(cpp_dev->cpp_clk[msm_micro_iface_idx], - CLK_RESET_ASSERT); + rc = reset_control_assert(cpp_dev->micro_iface_reset); if (rc) { - pr_err("%s:micro_iface_clk assert failed\n", + pr_err("%s:micro_iface_reset assert failed\n", __func__); return -EINVAL; } @@ -129,10 +120,9 @@ int msm_cpp_set_micro_clk(struct cpp_device *cpp_dev) */ usleep_range(1000, 1200); - rc = clk_reset(cpp_dev->cpp_clk[msm_micro_iface_idx], - CLK_RESET_DEASSERT); + rc = reset_control_deassert(cpp_dev->micro_iface_reset); if (rc) { - pr_err("%s:micro_iface_clk de-assert failed\n", __func__); + pr_err("%s:micro_iface_reset de-assert failed\n", __func__); return -EINVAL; } |