diff options
author | Heiko Stuebner <heiko@sntech.de> | 2015-06-20 13:08:57 +0200 |
---|---|---|
committer | Huang, Tao <huangtao@rock-chips.com> | 2016-03-01 17:11:44 +0800 |
commit | 5dacd5fa113fda937e03236478e5c0014a2fa664 (patch) | |
tree | 8a8ca9199111340b6199f8622f45b5ffed58ce38 /drivers/clk/rockchip/clk.c | |
parent | 4db3d2b3f5f1457120ed0d34232b407b3dbae860 (diff) |
UPSTREAM: clk: rockchip: add a factor clock type
Add a clock type for fixed factor clocks. This allows us to define fixed
factor clocks where they appear in the clock hierarchy instead of in the
init function.
The additional factor_gate type, finally allows us to model some last
parts of the clock tree correctly.
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
(cherry picked from commit 29a30c269aba4223e2a8b443f443d7def1e43fea)
Change-Id: Ie4ec8b9d9199cdbe0be045c2ed4c270029e37949
Signed-off-by: Xing Zheng <zhengxing@rock-chips.com>
Diffstat (limited to 'drivers/clk/rockchip/clk.c')
-rw-r--r-- | drivers/clk/rockchip/clk.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index 9b642e0357da..3c73703fb180 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -262,6 +262,53 @@ static struct clk *rockchip_clk_register_frac_branch(const char *name, return clk; } +static struct clk *rockchip_clk_register_factor_branch(const char *name, + const char *const *parent_names, u8 num_parents, + void __iomem *base, unsigned int mult, unsigned int div, + int gate_offset, u8 gate_shift, u8 gate_flags, + unsigned long flags, spinlock_t *lock) +{ + struct clk *clk; + struct clk_gate *gate = NULL; + struct clk_fixed_factor *fix = NULL; + + /* without gate, register a simple factor clock */ + if (gate_offset == 0) { + return clk_register_fixed_factor(NULL, name, + parent_names[0], flags, mult, + div); + } + + gate = kzalloc(sizeof(*gate), GFP_KERNEL); + if (!gate) + return ERR_PTR(-ENOMEM); + + gate->flags = gate_flags; + gate->reg = base + gate_offset; + gate->bit_idx = gate_shift; + gate->lock = lock; + + fix = kzalloc(sizeof(*fix), GFP_KERNEL); + if (!fix) { + kfree(gate); + return ERR_PTR(-ENOMEM); + } + + fix->mult = mult; + fix->div = div; + + clk = clk_register_composite(NULL, name, parent_names, num_parents, + NULL, NULL, + &fix->hw, &clk_fixed_factor_ops, + &gate->hw, &clk_gate_ops, flags); + if (IS_ERR(clk)) { + kfree(fix); + kfree(gate); + } + + return clk; +} + static DEFINE_SPINLOCK(clk_lock); static struct clk **clk_table; static void __iomem *reg_base; @@ -397,6 +444,14 @@ void __init rockchip_clk_register_branches( reg_base + list->muxdiv_offset, list->div_shift, list->div_flags, &clk_lock); break; + case branch_factor: + clk = rockchip_clk_register_factor_branch( + list->name, list->parent_names, + list->num_parents, reg_base, + list->div_shift, list->div_width, + list->gate_offset, list->gate_shift, + list->gate_flags, flags, &clk_lock); + break; } /* none of the cases above matched */ |