aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/clk-gate.c
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@st.com>2012-04-17 07:15:37 -0400
committerMike Turquette <mturquette@linaro.org>2012-04-24 19:37:40 -0400
commitfbc42aab543307e9bfc1dfb029db929f3fafcacd (patch)
treea9d86234545e39a1ce8fd69302c2b1ff85d292c7 /drivers/clk/clk-gate.c
parent1f73f31ad6e37df0679f6842b7405d96515ec8b1 (diff)
clk: clk-gate: Create clk_gate_endisable()
This patch tries to remove duplicate code for clk_gate clocks. This creates another routine clk_gate_endisable() which will take care of enable/disable clock with knowledge of CLK_GATE_SET_TO_DISABLE flag. It works on following logic: For enabling clock, enable = 1 set2dis = 1 -> clear bit -> set = 0 set2dis = 0 -> set bit -> set = 1 For disabling clock, enable = 0 set2dis = 1 -> set bit -> set = 1 set2dis = 0 -> clear bit -> set = 0 So, result is always: enable xor set2dis. Signed-off-by: Viresh Kumar <viresh.kumar@st.com> Signed-off-by: Mike Turquette <mturquette@linaro.org>
Diffstat (limited to 'drivers/clk/clk-gate.c')
-rw-r--r--drivers/clk/clk-gate.c54
1 files changed, 25 insertions, 29 deletions
diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c
index 42a4b941b6e7..00216164fb9d 100644
--- a/drivers/clk/clk-gate.c
+++ b/drivers/clk/clk-gate.c
@@ -28,32 +28,38 @@
28 28
29#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) 29#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
30 30
31static void clk_gate_set_bit(struct clk_gate *gate) 31/*
32 * It works on following logic:
33 *
34 * For enabling clock, enable = 1
35 * set2dis = 1 -> clear bit -> set = 0
36 * set2dis = 0 -> set bit -> set = 1
37 *
38 * For disabling clock, enable = 0
39 * set2dis = 1 -> set bit -> set = 1
40 * set2dis = 0 -> clear bit -> set = 0
41 *
42 * So, result is always: enable xor set2dis.
43 */
44static void clk_gate_endisable(struct clk_hw *hw, int enable)
32{ 45{
33 u32 reg; 46 struct clk_gate *gate = to_clk_gate(hw);
47 int set = gate->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0;
34 unsigned long flags = 0; 48 unsigned long flags = 0;
49 u32 reg;
50
51 set ^= enable;
35 52
36 if (gate->lock) 53 if (gate->lock)
37 spin_lock_irqsave(gate->lock, flags); 54 spin_lock_irqsave(gate->lock, flags);
38 55
39 reg = readl(gate->reg); 56 reg = readl(gate->reg);
40 reg |= BIT(gate->bit_idx);
41 writel(reg, gate->reg);
42
43 if (gate->lock)
44 spin_unlock_irqrestore(gate->lock, flags);
45}
46
47static void clk_gate_clear_bit(struct clk_gate *gate)
48{
49 u32 reg;
50 unsigned long flags = 0;
51 57
52 if (gate->lock) 58 if (set)
53 spin_lock_irqsave(gate->lock, flags); 59 reg |= BIT(gate->bit_idx);
60 else
61 reg &= ~BIT(gate->bit_idx);
54 62
55 reg = readl(gate->reg);
56 reg &= ~BIT(gate->bit_idx);
57 writel(reg, gate->reg); 63 writel(reg, gate->reg);
58 64
59 if (gate->lock) 65 if (gate->lock)
@@ -62,24 +68,14 @@ static void clk_gate_clear_bit(struct clk_gate *gate)
62 68
63static int clk_gate_enable(struct clk_hw *hw) 69static int clk_gate_enable(struct clk_hw *hw)
64{ 70{
65 struct clk_gate *gate = to_clk_gate(hw); 71 clk_gate_endisable(hw, 1);
66
67 if (gate->flags & CLK_GATE_SET_TO_DISABLE)
68 clk_gate_clear_bit(gate);
69 else
70 clk_gate_set_bit(gate);
71 72
72 return 0; 73 return 0;
73} 74}
74 75
75static void clk_gate_disable(struct clk_hw *hw) 76static void clk_gate_disable(struct clk_hw *hw)
76{ 77{
77 struct clk_gate *gate = to_clk_gate(hw); 78 clk_gate_endisable(hw, 0);
78
79 if (gate->flags & CLK_GATE_SET_TO_DISABLE)
80 clk_gate_set_bit(gate);
81 else
82 clk_gate_clear_bit(gate);
83} 79}
84 80
85static int clk_gate_is_enabled(struct clk_hw *hw) 81static int clk_gate_is_enabled(struct clk_hw *hw)