Loading drivers/clk/qcom/clk-regmap.c +9 −0 Original line number Diff line number Diff line Loading @@ -269,6 +269,7 @@ EXPORT_SYMBOL(clk_is_regmap_clk); */ int devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk) { const struct clk_ops *ops; int ret; rclk->dev = dev; Loading @@ -278,6 +279,14 @@ int devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk) else if (dev && dev->parent) rclk->regmap = dev_get_regmap(dev->parent, NULL); if (rclk->flags & QCOM_CLK_IS_CRITICAL) { ops = rclk->hw.init->ops; if (ops && ops->enable) ops->enable(&rclk->hw); return 0; } ret = devm_clk_hw_register(dev, &rclk->hw); if (!ret) list_add(&rclk->list_node, &clk_regmap_list); Loading drivers/clk/qcom/clk-regmap.h +2 −0 Original line number Diff line number Diff line Loading @@ -51,6 +51,8 @@ struct clk_regmap { struct clk_regmap_ops *ops; struct list_head list_node; struct device *dev; #define QCOM_CLK_IS_CRITICAL BIT(0) unsigned long flags; }; #define to_clk_regmap(_hw) container_of(_hw, struct clk_regmap, hw) Loading drivers/clk/qcom/common.c +50 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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]) Loading @@ -329,6 +371,14 @@ int qcom_cc_really_probe(struct platform_device *pdev, return ret; clk_hw_populate_clock_opp_table(dev->of_node, &rclks[i]->hw); /* * Critical clocks are enabled by devm_clk_register_regmap() * and registration skipped. So remove from rclks so that the * get() callback returns NULL and client requests are stubbed. */ if (rclks[i]->flags & QCOM_CLK_IS_CRITICAL) rclks[i] = NULL; } ret = devm_of_clk_add_hw_provider(dev, qcom_cc_clk_hw_get, cc); Loading drivers/clk/qcom/common.h +5 −0 Original line number Diff line number Diff line Loading @@ -84,4 +84,9 @@ int qcom_cc_runtime_init(struct platform_device *pdev, int qcom_cc_runtime_suspend(struct device *dev); int qcom_cc_runtime_resume(struct device *dev); static inline const char *qcom_clk_hw_get_name(const struct clk_hw *hw) { return hw->init ? hw->init->name : clk_hw_get_name(hw); } #endif Loading
drivers/clk/qcom/clk-regmap.c +9 −0 Original line number Diff line number Diff line Loading @@ -269,6 +269,7 @@ EXPORT_SYMBOL(clk_is_regmap_clk); */ int devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk) { const struct clk_ops *ops; int ret; rclk->dev = dev; Loading @@ -278,6 +279,14 @@ int devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk) else if (dev && dev->parent) rclk->regmap = dev_get_regmap(dev->parent, NULL); if (rclk->flags & QCOM_CLK_IS_CRITICAL) { ops = rclk->hw.init->ops; if (ops && ops->enable) ops->enable(&rclk->hw); return 0; } ret = devm_clk_hw_register(dev, &rclk->hw); if (!ret) list_add(&rclk->list_node, &clk_regmap_list); Loading
drivers/clk/qcom/clk-regmap.h +2 −0 Original line number Diff line number Diff line Loading @@ -51,6 +51,8 @@ struct clk_regmap { struct clk_regmap_ops *ops; struct list_head list_node; struct device *dev; #define QCOM_CLK_IS_CRITICAL BIT(0) unsigned long flags; }; #define to_clk_regmap(_hw) container_of(_hw, struct clk_regmap, hw) Loading
drivers/clk/qcom/common.c +50 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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]) Loading @@ -329,6 +371,14 @@ int qcom_cc_really_probe(struct platform_device *pdev, return ret; clk_hw_populate_clock_opp_table(dev->of_node, &rclks[i]->hw); /* * Critical clocks are enabled by devm_clk_register_regmap() * and registration skipped. So remove from rclks so that the * get() callback returns NULL and client requests are stubbed. */ if (rclks[i]->flags & QCOM_CLK_IS_CRITICAL) rclks[i] = NULL; } ret = devm_of_clk_add_hw_provider(dev, qcom_cc_clk_hw_get, cc); Loading
drivers/clk/qcom/common.h +5 −0 Original line number Diff line number Diff line Loading @@ -84,4 +84,9 @@ int qcom_cc_runtime_init(struct platform_device *pdev, int qcom_cc_runtime_suspend(struct device *dev); int qcom_cc_runtime_resume(struct device *dev); static inline const char *qcom_clk_hw_get_name(const struct clk_hw *hw) { return hw->init ? hw->init->name : clk_hw_get_name(hw); } #endif