2 * Copyright (C) 2010-2011 Canonical Ltd <jeremy.kerr@canonical.com>
3 * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Gated clock implementation
12 #include <linux/clk-provider.h>
13 #include <linux/module.h>
14 #include <linux/slab.h>
16 #include <linux/err.h>
17 #include <linux/string.h>
20 * DOC: basic gatable clock which can gate and ungate it's ouput
22 * Traits of this clock:
23 * prepare - clk_(un)prepare only ensures parent is (un)prepared
24 * enable - clk_enable and clk_disable are functional & control gating
25 * rate - inherits rate from parent. No clk_set_rate support
26 * parent - fixed parent. No clk_set_parent support
29 #define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
31 static void clk_gate_set_bit(struct clk_gate
*gate
)
34 unsigned long flags
= 0;
37 spin_lock_irqsave(gate
->lock
, flags
);
39 reg
= readl(gate
->reg
);
40 reg
|= BIT(gate
->bit_idx
);
41 writel(reg
, gate
->reg
);
44 spin_unlock_irqrestore(gate
->lock
, flags
);
47 static void clk_gate_clear_bit(struct clk_gate
*gate
)
50 unsigned long flags
= 0;
53 spin_lock_irqsave(gate
->lock
, flags
);
55 reg
= readl(gate
->reg
);
56 reg
&= ~BIT(gate
->bit_idx
);
57 writel(reg
, gate
->reg
);
60 spin_unlock_irqrestore(gate
->lock
, flags
);
63 static int clk_gate_enable(struct clk_hw
*hw
)
65 struct clk_gate
*gate
= to_clk_gate(hw
);
67 if (gate
->flags
& CLK_GATE_SET_TO_DISABLE
)
68 clk_gate_clear_bit(gate
);
70 clk_gate_set_bit(gate
);
74 EXPORT_SYMBOL_GPL(clk_gate_enable
);
76 static void clk_gate_disable(struct clk_hw
*hw
)
78 struct clk_gate
*gate
= to_clk_gate(hw
);
80 if (gate
->flags
& CLK_GATE_SET_TO_DISABLE
)
81 clk_gate_set_bit(gate
);
83 clk_gate_clear_bit(gate
);
85 EXPORT_SYMBOL_GPL(clk_gate_disable
);
87 static int clk_gate_is_enabled(struct clk_hw
*hw
)
90 struct clk_gate
*gate
= to_clk_gate(hw
);
92 reg
= readl(gate
->reg
);
94 /* if a set bit disables this clk, flip it before masking */
95 if (gate
->flags
& CLK_GATE_SET_TO_DISABLE
)
96 reg
^= BIT(gate
->bit_idx
);
98 reg
&= BIT(gate
->bit_idx
);
102 EXPORT_SYMBOL_GPL(clk_gate_is_enabled
);
104 struct clk_ops clk_gate_ops
= {
105 .enable
= clk_gate_enable
,
106 .disable
= clk_gate_disable
,
107 .is_enabled
= clk_gate_is_enabled
,
109 EXPORT_SYMBOL_GPL(clk_gate_ops
);
111 struct clk
*clk_register_gate(struct device
*dev
, const char *name
,
112 const char *parent_name
, unsigned long flags
,
113 void __iomem
*reg
, u8 bit_idx
,
114 u8 clk_gate_flags
, spinlock_t
*lock
)
116 struct clk_gate
*gate
;
119 gate
= kzalloc(sizeof(struct clk_gate
), GFP_KERNEL
);
122 pr_err("%s: could not allocate gated clk\n", __func__
);
126 /* struct clk_gate assignments */
128 gate
->bit_idx
= bit_idx
;
129 gate
->flags
= clk_gate_flags
;
133 gate
->parent
[0] = kstrdup(parent_name
, GFP_KERNEL
);
134 if (!gate
->parent
[0])
138 clk
= clk_register(dev
, name
,
139 &clk_gate_ops
, &gate
->hw
,
141 (parent_name
? 1 : 0),
146 kfree(gate
->parent
[0]);