Re: [PATCH RFT V3 3/8] clk: gate: add explicit big endian support

2019-04-18 Thread Stephen Boyd
Quoting Jonas Gorski (2019-04-18 04:12:06)
> Add a clock specific flag to switch register accesses to big endian, to
> allow runtime configuration of big endian gated clocks.
> 
> Signed-off-by: Jonas Gorski 
> ---

Applied to clk-next



[PATCH RFT V3 3/8] clk: gate: add explicit big endian support

2019-04-18 Thread Jonas Gorski
Add a clock specific flag to switch register accesses to big endian, to
allow runtime configuration of big endian gated clocks.

Signed-off-by: Jonas Gorski 
---
V2 -> V3:
 * drop unneeded else in clk_gate_readl
V1 -> V2:
 * switch from global to local flag

 drivers/clk/clk-gate.c   | 22 +++---
 include/linux/clk-provider.h |  4 
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c
index f05823cd9b21..6ced7b1f5585 100644
--- a/drivers/clk/clk-gate.c
+++ b/drivers/clk/clk-gate.c
@@ -23,6 +23,22 @@
  * parent - fixed parent.  No clk_set_parent support
  */
 
+static inline u32 clk_gate_readl(struct clk_gate *gate)
+{
+   if (gate->flags & CLK_GATE_BIG_ENDIAN)
+   return ioread32be(gate->reg);
+
+   return clk_readl(gate->reg);
+}
+
+static inline void clk_gate_writel(struct clk_gate *gate, u32 val)
+{
+   if (gate->flags & CLK_GATE_BIG_ENDIAN)
+   iowrite32be(val, gate->reg);
+   else
+   clk_writel(val, gate->reg);
+}
+
 /*
  * It works on following logic:
  *
@@ -55,7 +71,7 @@ static void clk_gate_endisable(struct clk_hw *hw, int enable)
if (set)
reg |= BIT(gate->bit_idx);
} else {
-   reg = clk_readl(gate->reg);
+   reg = clk_gate_readl(gate);
 
if (set)
reg |= BIT(gate->bit_idx);
@@ -63,7 +79,7 @@ static void clk_gate_endisable(struct clk_hw *hw, int enable)
reg &= ~BIT(gate->bit_idx);
}
 
-   clk_writel(reg, gate->reg);
+   clk_gate_writel(gate, reg);
 
if (gate->lock)
spin_unlock_irqrestore(gate->lock, flags);
@@ -88,7 +104,7 @@ int clk_gate_is_enabled(struct clk_hw *hw)
u32 reg;
struct clk_gate *gate = to_clk_gate(hw);
 
-   reg = clk_readl(gate->reg);
+   reg = clk_gate_readl(gate);
 
/* if a set bit disables this clk, flip it before masking */
if (gate->flags & CLK_GATE_SET_TO_DISABLE)
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 8c07d810acf5..8576c2dbc639 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -348,6 +348,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_BIG_ENDIAN - by default little endian register accesses are used 
for
+ * the gate register.  Setting this flag makes the register accesses big
+ * endian.
  */
 struct clk_gate {
struct clk_hw hw;
@@ -361,6 +364,7 @@ struct clk_gate {
 
 #define CLK_GATE_SET_TO_DISABLEBIT(0)
 #define CLK_GATE_HIWORD_MASK   BIT(1)
+#define CLK_GATE_BIG_ENDIANBIT(2)
 
 extern const struct clk_ops clk_gate_ops;
 struct clk *clk_register_gate(struct device *dev, const char *name,
-- 
2.13.2