diff options
author | Jonas Gorski <jonas.gorski@gmail.com> | 2019-04-18 07:12:06 -0400 |
---|---|---|
committer | Stephen Boyd <sboyd@kernel.org> | 2019-04-23 13:57:48 -0400 |
commit | d1c8a501ec07290da5cc2d8dedb6692cf89078d8 (patch) | |
tree | e5a3bf9dd51357e5e87a08ac1b346c6fb8b35d69 | |
parent | 58a2b4c9bdf98452fec95bb1a5eeed60c01f621a (diff) |
clk: gate: add explicit big endian support
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 <jonas.gorski@gmail.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
-rw-r--r-- | drivers/clk/clk-gate.c | 22 | ||||
-rw-r--r-- | 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 @@ | |||
23 | * parent - fixed parent. No clk_set_parent support | 23 | * parent - fixed parent. No clk_set_parent support |
24 | */ | 24 | */ |
25 | 25 | ||
26 | static inline u32 clk_gate_readl(struct clk_gate *gate) | ||
27 | { | ||
28 | if (gate->flags & CLK_GATE_BIG_ENDIAN) | ||
29 | return ioread32be(gate->reg); | ||
30 | |||
31 | return clk_readl(gate->reg); | ||
32 | } | ||
33 | |||
34 | static inline void clk_gate_writel(struct clk_gate *gate, u32 val) | ||
35 | { | ||
36 | if (gate->flags & CLK_GATE_BIG_ENDIAN) | ||
37 | iowrite32be(val, gate->reg); | ||
38 | else | ||
39 | clk_writel(val, gate->reg); | ||
40 | } | ||
41 | |||
26 | /* | 42 | /* |
27 | * It works on following logic: | 43 | * It works on following logic: |
28 | * | 44 | * |
@@ -55,7 +71,7 @@ static void clk_gate_endisable(struct clk_hw *hw, int enable) | |||
55 | if (set) | 71 | if (set) |
56 | reg |= BIT(gate->bit_idx); | 72 | reg |= BIT(gate->bit_idx); |
57 | } else { | 73 | } else { |
58 | reg = clk_readl(gate->reg); | 74 | reg = clk_gate_readl(gate); |
59 | 75 | ||
60 | if (set) | 76 | if (set) |
61 | reg |= BIT(gate->bit_idx); | 77 | reg |= BIT(gate->bit_idx); |
@@ -63,7 +79,7 @@ static void clk_gate_endisable(struct clk_hw *hw, int enable) | |||
63 | reg &= ~BIT(gate->bit_idx); | 79 | reg &= ~BIT(gate->bit_idx); |
64 | } | 80 | } |
65 | 81 | ||
66 | clk_writel(reg, gate->reg); | 82 | clk_gate_writel(gate, reg); |
67 | 83 | ||
68 | if (gate->lock) | 84 | if (gate->lock) |
69 | spin_unlock_irqrestore(gate->lock, flags); | 85 | spin_unlock_irqrestore(gate->lock, flags); |
@@ -88,7 +104,7 @@ int clk_gate_is_enabled(struct clk_hw *hw) | |||
88 | u32 reg; | 104 | u32 reg; |
89 | struct clk_gate *gate = to_clk_gate(hw); | 105 | struct clk_gate *gate = to_clk_gate(hw); |
90 | 106 | ||
91 | reg = clk_readl(gate->reg); | 107 | reg = clk_gate_readl(gate); |
92 | 108 | ||
93 | /* if a set bit disables this clk, flip it before masking */ | 109 | /* if a set bit disables this clk, flip it before masking */ |
94 | if (gate->flags & CLK_GATE_SET_TO_DISABLE) | 110 | if (gate->flags & CLK_GATE_SET_TO_DISABLE) |
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 7c6861995505..7d5a32d83655 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h | |||
@@ -349,6 +349,9 @@ void of_fixed_clk_setup(struct device_node *np); | |||
349 | * of this register, and mask of gate bits are in higher 16-bit of this | 349 | * of this register, and mask of gate bits are in higher 16-bit of this |
350 | * register. While setting the gate bits, higher 16-bit should also be | 350 | * register. While setting the gate bits, higher 16-bit should also be |
351 | * updated to indicate changing gate bits. | 351 | * updated to indicate changing gate bits. |
352 | * CLK_GATE_BIG_ENDIAN - by default little endian register accesses are used for | ||
353 | * the gate register. Setting this flag makes the register accesses big | ||
354 | * endian. | ||
352 | */ | 355 | */ |
353 | struct clk_gate { | 356 | struct clk_gate { |
354 | struct clk_hw hw; | 357 | struct clk_hw hw; |
@@ -362,6 +365,7 @@ struct clk_gate { | |||
362 | 365 | ||
363 | #define CLK_GATE_SET_TO_DISABLE BIT(0) | 366 | #define CLK_GATE_SET_TO_DISABLE BIT(0) |
364 | #define CLK_GATE_HIWORD_MASK BIT(1) | 367 | #define CLK_GATE_HIWORD_MASK BIT(1) |
368 | #define CLK_GATE_BIG_ENDIAN BIT(2) | ||
365 | 369 | ||
366 | extern const struct clk_ops clk_gate_ops; | 370 | extern const struct clk_ops clk_gate_ops; |
367 | struct clk *clk_register_gate(struct device *dev, const char *name, | 371 | struct clk *clk_register_gate(struct device *dev, const char *name, |