diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index 3f20d378c293..bfe3f583f971 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -232,6 +232,47 @@ static void qcom_cc_drop_protected(struct device *dev, struct qcom_cc *cc) } } +/* Set QCOM_CLK_IS_CRITICAL on clocks specified in dt */ +static void qcom_cc_set_critical(struct device *dev, struct qcom_cc *cc) +{ + struct of_phandle_args args; + struct device_node *np; + struct property *prop; + const __be32 *p; + u32 clock_idx; + u32 i; + int cnt; + + of_property_for_each_u32(dev->of_node, "qcom,critical-clocks", prop, p, i) { + if (i >= cc->num_rclks) + continue; + + cc->rclks[i]->flags |= QCOM_CLK_IS_CRITICAL; + } + + of_property_for_each_u32(dev->of_node, "qcom,critical-devices", prop, p, i) { + np = of_find_node_by_phandle(i); + if (!np) + continue; + + cnt = of_count_phandle_with_args(np, "clocks", "#clock-cells"); + + for (i = 0; i < cnt; i++) { + of_parse_phandle_with_args(np, "clocks", "#clock-cells", + i, &args); + clock_idx = args.args[0]; + + if (args.np != dev->of_node || clock_idx >= cc->num_rclks) + continue; + + cc->rclks[clock_idx]->flags |= QCOM_CLK_IS_CRITICAL; + of_node_put(args.np); + } + + of_node_put(np); + } +} + static struct clk_hw *qcom_cc_clk_hw_get(struct of_phandle_args *clkspec, void *data) { @@ -310,6 +351,7 @@ int qcom_cc_really_probe(struct platform_device *pdev, cc->num_clk_hws = num_clk_hws; qcom_cc_drop_protected(dev, cc); + qcom_cc_set_critical(dev, cc); for (i = 0; i < num_clk_hws; i++) { if (!clk_hws[i])