Merge "msm: camera: Add support for reset controller framework"

This commit is contained in:
Linux Build Service Account 2016-09-20 10:20:45 -07:00 committed by Gerrit - the friendly Code Review server
commit 9e2d528dc4
8 changed files with 70 additions and 16 deletions

View file

@ -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";
};
};

View file

@ -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>;

View file

@ -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>;

View file

@ -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,

View file

@ -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
*

View file

@ -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);

View file

@ -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;

View file

@ -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;
}