[PATCH 20/24] clk: implement CLK_SET_RATE_UNGATE

Sascha Hauer s.hauer at pengutronix.de
Wed Jun 2 02:55:03 PDT 2021


Some clocks need to be turned on in oder to change their rate. Implement
CLK_SET_RATE_UNGATE to support these.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/clk/clk.c   | 12 +++++++++++-
 include/linux/clk.h |  1 +
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 74e2f5d783..fe2424dc8a 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -172,6 +172,12 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 	if (!clk->ops->set_rate)
 		return -ENOSYS;
 
+	if (clk->flags & CLK_SET_RATE_UNGATE) {
+		ret = clk_enable(clk);
+		if (ret)
+			return ret;
+	}
+
 	parent = clk_get_parent(clk);
 	if (parent) {
 		parent_rate = clk_get_rate(parent);
@@ -179,7 +185,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 		if (clk->flags & CLK_OPS_PARENT_ENABLE) {
 			ret = clk_enable(parent);
 			if (ret)
-				return ret;
+				goto out;
 		}
 	}
 
@@ -190,6 +196,10 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 	if (parent && clk->flags & CLK_OPS_PARENT_ENABLE)
 		clk_disable(parent);
 
+out:
+	if (clk->flags & CLK_SET_RATE_UNGATE)
+		clk_disable(clk);
+
 	return ret;
 }
 
diff --git a/include/linux/clk.h b/include/linux/clk.h
index d53699a874..72971c8e27 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -335,6 +335,7 @@ static inline void clk_put(struct clk *clk)
 #define CLK_IGNORE_UNUSED       (1 << 3) /* do not gate even if unused */
 #define CLK_GET_RATE_NOCACHE    (1 << 6) /* do not use the cached clk rate */
 #define CLK_SET_RATE_NO_REPARENT (1 << 7) /* don't re-parent on rate change */
+#define CLK_SET_RATE_UNGATE     (1 << 10) /* clock needs to run to set rate */
 #define CLK_IS_CRITICAL         (1 << 11) /* do not gate, ever */
 /* parents need enable during gate/ungate, set rate and re-parent */
 #define CLK_OPS_PARENT_ENABLE   (1 << 12)
-- 
2.29.2




More information about the barebox mailing list