Skip to contentSkip to conversation

clk: gate: add CLK_GATE_ALWAYS_ON

PATCH New Shaojie Sun 3 participants 3 messages Aug 6, 2013 Common clk

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 clk: gate: add CLK_GATE_ALWAYS_ON

By default gate clock could be enable and disable. but in some debug condition, must keep clock on, and never be closed. setting this flag then gate clock never be closed.

---
 drivers/clk/clk-gate.c       |   24 ++++++++++++++++++++++++
 include/linux/clk-provider.h |    4 ++++
 2 files changed, 28 insertions(+)
drivers/clk/clk-gate.c +24 -0
index 790306e..cc2b00e 100644
@@ -15,6 +15,7 @@
 #include <linux/io.h>
 #include <linux/err.h>
 #include <linux/string.h>
+#include <linux/device.h>
 
 /**
  * DOC: basic gatable clock which can gate and ungate it's ouput
@@ -48,6 +49,9 @@ static void clk_gate_endisable(struct clk_hw *hw, int enable)
 	unsigned long flags = 0;
 	u32 reg;
 
+	if (!enable && (gate->flags & CLK_GATE_ALWAYS_ON))
+		return;
+
 	set ^= enable;
 
 	if (gate->lock)
@@ -159,5 +163,25 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
 	if (IS_ERR(clk))
 		kfree(gate);
 
+	if (clk_gate_flags & CLK_GATE_ALWAYS_ON) {
+		int ret;
+		if (flags & CLK_SET_PARENT_GATE)
+			pr_debug("%s: %salways on, but need parent gate.\n",
+					__func__, name);
+
+		ret = clk_prepare(clk);
+		if (ret) {
+			pr_debug("%s: %s could not be prepared.\n",
+					__func__, name);
+			return clk;
+		}
+		ret = clk_enable(clk);
+		if (ret) {
+			pr_debug("%s: %s could not be enabled.\n",
+					__func__, name);
+			clk_unprepare(clk);
+		}
+	}
+
 	return clk;
 }
include/linux/clk-provider.h +4 -0
index 1ec14a7..641422c 100644
@@ -214,6 +214,9 @@ void of_fixed_clk_setup(struct device_node *np);
  *   of this register, and mask of gate bits are in higher 16-bit of this
  *   register.  While setting the gate bits, higher 16-bit should also be
  *   updated to indicate changing gate bits.
+ * CLK_GATE_ALWAYS_ON - by default this clock could be enable and disable. but
+ *   in some debug condition, must keep this clock on, and never be closed.
+ *   setting this flag then this clock never be closed.
  */
 struct clk_gate {
 	struct clk_hw hw;
@@ -225,6 +228,7 @@ struct clk_gate {
 
 #define CLK_GATE_SET_TO_DISABLE		BIT(0)
 #define CLK_GATE_HIWORD_MASK		BIT(1)
+#define CLK_GATE_ALWAYS_ON		BIT(4)
 
 extern const struct clk_ops clk_gate_ops;
 struct clk *clk_register_gate(struct device *dev, const char *name,
Signature · 1 line
1.7.9.5
#1 lore raw

PATCH 1/1 clk: gate: add CLK_GATE_ALWAYS_ON

Added linaro-kernel & patches at linaro.org in cc list..

Quoted 3 lines · Shaojie Sun

By default gate clock could be enable and disable. but in some debug condition, must keep clock on, and never be closed. setting this flag then gate clock never be closed.

Consider rewriting it as:

By default gate clk can be enabled/disabled but during debugging we may want to disable clk-disabling feature.

This patch adds a flag for it..

Quoted 5 lines
---
 drivers/clk/clk-gate.c       |   24 ++++++++++++++++++++++++
 include/linux/clk-provider.h |    4 ++++
 2 files changed, 28 insertions(+)

Honestly speaking, I am not sure if this patch is really required or not. And so Mike can decide on that. I will do a simple code review in that time.

drivers/clk/clk-gate.c line 18

Quoted 9 lines
drivers/clk/clk-gate.c +1 -0
index 790306e..cc2b00e 100644
@@ -15,6 +15,7 @@
 #include <linux/io.h>
 #include <linux/err.h>
 #include <linux/string.h>
+#include <linux/device.h>

why?

Quoted 24 lines
drivers/clk/clk-gate.c +11 -0
 /**
  * DOC: basic gatable clock which can gate and ungate it's ouput
@@ -48,6 +49,9 @@ static void clk_gate_endisable(struct clk_hw *hw, int enable)
        unsigned long flags = 0;
        u32 reg;
 
+       if (!enable && (gate->flags & CLK_GATE_ALWAYS_ON))
+               return;
+
        set ^= enable;
 
        if (gate->lock)
@@ -159,5 +163,25 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
        if (IS_ERR(clk))
                kfree(gate);
 
+       if (clk_gate_flags & CLK_GATE_ALWAYS_ON) {
+               int ret;
+               if (flags & CLK_SET_PARENT_GATE)
+                       pr_debug("%s: %salways on, but need parent gate.\n",
+                                       __func__, name);
+
+               ret = clk_prepare(clk);
+               if (ret) {

drivers/clk/clk-gate.c struct clk *clk_register_gate(struct device *dev, const char *name, · line 183

Quoted 10 lines
drivers/clk/clk-gate.c +10 -0
+                       pr_debug("%s: %s could not be prepared.\n",
+                                       __func__, name);
+                       return clk;
+               }
+               ret = clk_enable(clk);
+               if (ret) {
+                       pr_debug("%s: %s could not be enabled.\n",
+                                       __func__, name);
+                       clk_unprepare(clk);
+               }

Call clk_prepare_enable instead.

Quoted 9 lines
drivers/clk/clk-gate.c +2 -0
+       }
+
        return clk;
 }
include/linux/clk-provider.h +0 -0
index 1ec14a7..641422c 100644

include/linux/clk-provider.h void of_fixed_clk_setup(struct device_node *np); · line 219

Quoted 6 lines
include/linux/clk-provider.h +3 -0
@@ -214,6 +214,9 @@ void of_fixed_clk_setup(struct device_node *np);
  *   of this register, and mask of gate bits are in higher 16-bit of this
  *   register.  While setting the gate bits, higher 16-bit should also be
  *   updated to indicate changing gate bits.
+ * CLK_GATE_ALWAYS_ON - by default this clock could be enable and disable. but
+ *   in some debug condition, must keep this clock on, and never be closed.
+ *   setting this flag then this clock never be closed.

Copy some part from the commit log I just suggested..

If this flag is only for debugging we may name it that way.
Maybe: CLK_GATE_DBG_ALWAYS_ON ??

#2 lore raw

PATCH 1/1 clk: gate: add CLK_GATE_ALWAYS_ON

Quoting Viresh Kumar (2013-08-05 21:45:56)

Quoted 20 lines

Added linaro-kernel & patches at linaro.org in cc list..

Quoted 3 lines · Shaojie Sun

By default gate clock could be enable and disable. but in some debug condition, must keep clock on, and never be closed. setting this flag then gate clock never be closed.

Consider rewriting it as:

By default gate clk can be enabled/disabled but during debugging we may want to disable clk-disabling feature.

This patch adds a flag for it..

Quoted 5 lines
---
 drivers/clk/clk-gate.c       |   24 ++++++++++++++++++++++++
 include/linux/clk-provider.h |    4 ++++
 2 files changed, 28 insertions(+)
Quoted 3 lines

Honestly speaking, I am not sure if this patch is really required or not. And so Mike can decide on that. I will do a simple code review in that time.

I don't think this feature should be merged. Since it is purely for debug purposes, and the change is small and domain-specific, I'd rather have developers implement something like this locally during debug instead of merging it into mainline. An early return in clk_disable would suffice to do the same thing.

If many other developers find this to be extremely useful then I'll reconsider.

Thanks,
Mike

Quoted 70 lines

drivers/clk/clk-gate.c line 18

Quoted 10 lines
drivers/clk/clk-gate.c +1 -0
index 790306e..cc2b00e 100644
@@ -15,6 +15,7 @@
 #include <linux/io.h>
 #include <linux/err.h>
 #include <linux/string.h>
+#include <linux/device.h>

why?

Quoted 24 lines
drivers/clk/clk-gate.c +11 -0
 /**
  * DOC: basic gatable clock which can gate and ungate it's ouput
@@ -48,6 +49,9 @@ static void clk_gate_endisable(struct clk_hw *hw, int enable)
        unsigned long flags = 0;
        u32 reg;
 
+       if (!enable && (gate->flags & CLK_GATE_ALWAYS_ON))
+               return;
+
        set ^= enable;
 
        if (gate->lock)
@@ -159,5 +163,25 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
        if (IS_ERR(clk))
                kfree(gate);
 
+       if (clk_gate_flags & CLK_GATE_ALWAYS_ON) {
+               int ret;
+               if (flags & CLK_SET_PARENT_GATE)
+                       pr_debug("%s: %salways on, but need parent gate.\n",
+                                       __func__, name);
+
+               ret = clk_prepare(clk);
+               if (ret) {

drivers/clk/clk-gate.c struct clk *clk_register_gate(struct device *dev, const char *name, · line 183

Quoted 10 lines
drivers/clk/clk-gate.c +10 -0
+                       pr_debug("%s: %s could not be prepared.\n",
+                                       __func__, name);
+                       return clk;
+               }
+               ret = clk_enable(clk);
+               if (ret) {
+                       pr_debug("%s: %s could not be enabled.\n",
+                                       __func__, name);
+                       clk_unprepare(clk);
+               }

Call clk_prepare_enable instead.

Quoted 9 lines
drivers/clk/clk-gate.c +2 -0
+       }
+
        return clk;
 }
include/linux/clk-provider.h +0 -0
index 1ec14a7..641422c 100644

include/linux/clk-provider.h void of_fixed_clk_setup(struct device_node *np); · line 219

Quoted 6 lines
include/linux/clk-provider.h +3 -0
@@ -214,6 +214,9 @@ void of_fixed_clk_setup(struct device_node *np);
  *   of this register, and mask of gate bits are in higher 16-bit of this
  *   register.  While setting the gate bits, higher 16-bit should also be
  *   updated to indicate changing gate bits.
+ * CLK_GATE_ALWAYS_ON - by default this clock could be enable and disable. but
+ *   in some debug condition, must keep this clock on, and never be closed.
+ *   setting this flag then this clock never be closed.

Copy some part from the commit log I just suggested..

If this flag is only for debugging we may name it that way.
Maybe: CLK_GATE_DBG_ALWAYS_ON ??