summaryrefslogtreecommitdiff
path: root/drivers/clk/rockchip/clk.c
diff options
context:
space:
mode:
authorHeiko Stuebner <heiko@sntech.de>2015-06-20 13:08:57 +0200
committerHuang, Tao <huangtao@rock-chips.com>2016-03-01 17:11:44 +0800
commit5dacd5fa113fda937e03236478e5c0014a2fa664 (patch)
tree8a8ca9199111340b6199f8622f45b5ffed58ce38 /drivers/clk/rockchip/clk.c
parent4db3d2b3f5f1457120ed0d34232b407b3dbae860 (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.c55
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 */