aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-imx/clk-gate2.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-imx/clk-gate2.c')
-rw-r--r--arch/arm/mach-imx/clk-gate2.c47
1 files changed, 31 insertions, 16 deletions
diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c
index a2ecc006b322..4ba587da89d2 100644
--- a/arch/arm/mach-imx/clk-gate2.c
+++ b/arch/arm/mach-imx/clk-gate2.c
@@ -27,48 +27,61 @@
27 * parent - fixed parent. No clk_set_parent support 27 * parent - fixed parent. No clk_set_parent support
28 */ 28 */
29 29
30#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) 30struct clk_gate2 {
31 struct clk_hw hw;
32 void __iomem *reg;
33 u8 bit_idx;
34 u8 flags;
35 spinlock_t *lock;
36 unsigned int *share_count;
37};
38
39#define to_clk_gate2(_hw) container_of(_hw, struct clk_gate2, hw)
31 40
32static int clk_gate2_enable(struct clk_hw *hw) 41static int clk_gate2_enable(struct clk_hw *hw)
33{ 42{
34 struct clk_gate *gate = to_clk_gate(hw); 43 struct clk_gate2 *gate = to_clk_gate2(hw);
35 u32 reg; 44 u32 reg;
36 unsigned long flags = 0; 45 unsigned long flags = 0;
37 46
38 if (gate->lock) 47 spin_lock_irqsave(gate->lock, flags);
39 spin_lock_irqsave(gate->lock, flags); 48
49 if (gate->share_count && (*gate->share_count)++ > 0)
50 goto out;
40 51
41 reg = readl(gate->reg); 52 reg = readl(gate->reg);
42 reg |= 3 << gate->bit_idx; 53 reg |= 3 << gate->bit_idx;
43 writel(reg, gate->reg); 54 writel(reg, gate->reg);
44 55
45 if (gate->lock) 56out:
46 spin_unlock_irqrestore(gate->lock, flags); 57 spin_unlock_irqrestore(gate->lock, flags);
47 58
48 return 0; 59 return 0;
49} 60}
50 61
51static void clk_gate2_disable(struct clk_hw *hw) 62static void clk_gate2_disable(struct clk_hw *hw)
52{ 63{
53 struct clk_gate *gate = to_clk_gate(hw); 64 struct clk_gate2 *gate = to_clk_gate2(hw);
54 u32 reg; 65 u32 reg;
55 unsigned long flags = 0; 66 unsigned long flags = 0;
56 67
57 if (gate->lock) 68 spin_lock_irqsave(gate->lock, flags);
58 spin_lock_irqsave(gate->lock, flags); 69
70 if (gate->share_count && --(*gate->share_count) > 0)
71 goto out;
59 72
60 reg = readl(gate->reg); 73 reg = readl(gate->reg);
61 reg &= ~(3 << gate->bit_idx); 74 reg &= ~(3 << gate->bit_idx);
62 writel(reg, gate->reg); 75 writel(reg, gate->reg);
63 76
64 if (gate->lock) 77out:
65 spin_unlock_irqrestore(gate->lock, flags); 78 spin_unlock_irqrestore(gate->lock, flags);
66} 79}
67 80
68static int clk_gate2_is_enabled(struct clk_hw *hw) 81static int clk_gate2_is_enabled(struct clk_hw *hw)
69{ 82{
70 u32 reg; 83 u32 reg;
71 struct clk_gate *gate = to_clk_gate(hw); 84 struct clk_gate2 *gate = to_clk_gate2(hw);
72 85
73 reg = readl(gate->reg); 86 reg = readl(gate->reg);
74 87
@@ -87,21 +100,23 @@ static struct clk_ops clk_gate2_ops = {
87struct clk *clk_register_gate2(struct device *dev, const char *name, 100struct clk *clk_register_gate2(struct device *dev, const char *name,
88 const char *parent_name, unsigned long flags, 101 const char *parent_name, unsigned long flags,
89 void __iomem *reg, u8 bit_idx, 102 void __iomem *reg, u8 bit_idx,
90 u8 clk_gate2_flags, spinlock_t *lock) 103 u8 clk_gate2_flags, spinlock_t *lock,
104 unsigned int *share_count)
91{ 105{
92 struct clk_gate *gate; 106 struct clk_gate2 *gate;
93 struct clk *clk; 107 struct clk *clk;
94 struct clk_init_data init; 108 struct clk_init_data init;
95 109
96 gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); 110 gate = kzalloc(sizeof(struct clk_gate2), GFP_KERNEL);
97 if (!gate) 111 if (!gate)
98 return ERR_PTR(-ENOMEM); 112 return ERR_PTR(-ENOMEM);
99 113
100 /* struct clk_gate assignments */ 114 /* struct clk_gate2 assignments */
101 gate->reg = reg; 115 gate->reg = reg;
102 gate->bit_idx = bit_idx; 116 gate->bit_idx = bit_idx;
103 gate->flags = clk_gate2_flags; 117 gate->flags = clk_gate2_flags;
104 gate->lock = lock; 118 gate->lock = lock;
119 gate->share_count = share_count;
105 120
106 init.name = name; 121 init.name = name;
107 init.ops = &clk_gate2_ops; 122 init.ops = &clk_gate2_ops;