mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-11 07:03:09 -04:00
Merge "clk: qcom: Add properties for marking clocks as critical"
This commit is contained in:
commit
367c7ae1ca
4 changed files with 66 additions and 0 deletions
|
|
@ -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;
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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])
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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…
Reference in a new issue