diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index 0f17e4189986..19da2567eca6 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -272,6 +272,10 @@ int qcom_cc_really_probe(struct platform_device *pdev, if (ret) return ret; + ret = clk_vdd_proxy_vote(&pdev->dev, desc); + if (ret) + return ret; + if (desc->num_resets) { ret = devm_reset_controller_register(dev, &reset->rcdev); if (ret) @@ -363,6 +367,8 @@ void qcom_cc_sync_state(struct device *dev, const struct qcom_cc_desc *desc) { dev_info(dev, "sync-state\n"); clk_sync_state(dev); + + clk_vdd_proxy_unvote(dev, desc); } EXPORT_SYMBOL(qcom_cc_sync_state); diff --git a/drivers/clk/qcom/vdd-class.c b/drivers/clk/qcom/vdd-class.c index a8e0cd18eb99..602715b05ad7 100644 --- a/drivers/clk/qcom/vdd-class.c +++ b/drivers/clk/qcom/vdd-class.c @@ -200,3 +200,41 @@ int clk_regulator_init(struct device *dev, const struct qcom_cc_desc *desc) return 0; } +int clk_vdd_proxy_vote(struct device *dev, const struct qcom_cc_desc *desc) +{ + struct clk_vdd_class_data vdd_data; + struct clk_vdd_class *vdd_class; + u32 i; + int ret = 0; + + for (i = 0; i < desc->num_clk_regulators; i++) { + vdd_data.vdd_class = vdd_class = desc->clk_regulators[i]; + + ret = clk_vote_vdd_level(&vdd_data, + vdd_class->num_levels - 1); + if (ret) + WARN(ret, "%s failed, ret=%d\n", __func__, ret); + } + + return ret; +} + +int clk_vdd_proxy_unvote(struct device *dev, const struct qcom_cc_desc *desc) +{ + struct clk_vdd_class_data vdd_data; + struct clk_vdd_class *vdd_class; + u32 i; + int ret = 0; + + for (i = 0; i < desc->num_clk_regulators; i++) { + vdd_data.vdd_class = vdd_class = desc->clk_regulators[i]; + + ret = clk_unvote_vdd_level(&vdd_data, + vdd_class->num_levels - 1); + if (ret) + WARN(ret, "clk_unvote_vdd_level failed ret=%d\n", ret); + } + + return ret; +} + diff --git a/drivers/clk/qcom/vdd-class.h b/drivers/clk/qcom/vdd-class.h index 126aae47f728..f50ebe0a0e9d 100644 --- a/drivers/clk/qcom/vdd-class.h +++ b/drivers/clk/qcom/vdd-class.h @@ -71,4 +71,6 @@ int clk_find_vdd_level(struct clk_hw *hw, struct clk_vdd_class_data *vdd_data, int clk_vote_vdd_level(struct clk_vdd_class_data *vdd_class, int level); int clk_unvote_vdd_level(struct clk_vdd_class_data *vdd_class, int level); int clk_regulator_init(struct device *dev, const struct qcom_cc_desc *desc); +int clk_vdd_proxy_vote(struct device *dev, const struct qcom_cc_desc *desc); +int clk_vdd_proxy_unvote(struct device *dev, const struct qcom_cc_desc *desc); #endif