From 0022172cdd686b211c98ff9ad66333d930730fbf Mon Sep 17 00:00:00 2001 From: Mike Tipton Date: Wed, 4 Nov 2020 17:47:24 -0800 Subject: [PATCH] clk: qcom: Add properties for marking clocks as critical Some clocks are critical only on specific boards, i.e. clocks used to interface with external PMICs over I2C. Which clocks are critical depend on which I2C bus is chosen to connect the PMICs. To support this, add properties to set QCOM_CLK_IS_CRITICAL on a per-board basis. The qcom,critical-clocks property can be used to set QCOM_CLK_IS_CRITICAL on individual clocks. The qcom,critical-devices property can be used to set QCOM_CLK_IS_CRITICAL on all clocks used by specified devices. Change-Id: I42d61ec13225026ba7d0b78079cf7a2ab67339f2 Signed-off-by: Mike Tipton --- drivers/clk/qcom/common.c | 42 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) 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])