2 * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
8 * Standard functionality for the common clock API.
10 #include <linux/module.h>
11 #include <linux/clk-provider.h>
12 #include <linux/slab.h>
13 #include <linux/err.h>
16 * DOC: basic fixed multiplier and divider clock that cannot gate
18 * Traits of this clock:
19 * prepare - clk_prepare only ensures that parents are prepared
20 * enable - clk_enable only ensures that parents are enabled
21 * rate - rate is fixed. clk->rate = parent->rate / div * mult
22 * parent - fixed parent. No clk_set_parent support
25 #define to_clk_fixed_factor(_hw) container_of(_hw, struct clk_fixed_factor, hw)
27 static unsigned long clk_factor_recalc_rate(struct clk_hw
*hw
,
28 unsigned long parent_rate
)
30 struct clk_fixed_factor
*fix
= to_clk_fixed_factor(hw
);
32 return parent_rate
* fix
->mult
/ fix
->div
;
35 static long clk_factor_round_rate(struct clk_hw
*hw
, unsigned long rate
,
38 struct clk_fixed_factor
*fix
= to_clk_fixed_factor(hw
);
40 if (__clk_get_flags(hw
->clk
) & CLK_SET_RATE_PARENT
) {
41 unsigned long best_parent
;
43 best_parent
= (rate
/ fix
->mult
) * fix
->div
;
44 *prate
= __clk_round_rate(__clk_get_parent(hw
->clk
),
48 return (*prate
/ fix
->div
) * fix
->mult
;
51 static int clk_factor_set_rate(struct clk_hw
*hw
, unsigned long rate
,
52 unsigned long parent_rate
)
57 struct clk_ops clk_fixed_factor_ops
= {
58 .round_rate
= clk_factor_round_rate
,
59 .set_rate
= clk_factor_set_rate
,
60 .recalc_rate
= clk_factor_recalc_rate
,
62 EXPORT_SYMBOL_GPL(clk_fixed_factor_ops
);
64 struct clk
*clk_register_fixed_factor(struct device
*dev
, const char *name
,
65 const char *parent_name
, unsigned long flags
,
66 unsigned int mult
, unsigned int div
)
68 struct clk_fixed_factor
*fix
;
69 struct clk_init_data init
;
72 fix
= kmalloc(sizeof(*fix
), GFP_KERNEL
);
74 pr_err("%s: could not allocate fixed factor clk\n", __func__
);
75 return ERR_PTR(-ENOMEM
);
78 /* struct clk_fixed_factor assignments */
84 init
.ops
= &clk_fixed_factor_ops
;
85 init
.flags
= flags
| CLK_IS_BASIC
;
86 init
.parent_names
= &parent_name
;
89 clk
= clk_register(dev
, &fix
->hw
);