Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 367c7ae1 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "clk: qcom: Add properties for marking clocks as critical"

parents 6092c652 0022172c
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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);
+2 −0
Original line number Diff line number Diff line
@@ -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)

+50 −0
Original line number Diff line number Diff line
@@ -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);
+5 −0
Original line number Diff line number Diff line
@@ -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